blob: 517f3bcd938457bddf6897d88e157ca13f541d73 [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{
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
311 struct netdev_notifier_info *info = ndev;
312 struct net_device *dev = info->dev;
313#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 struct net_device *dev = ndev;
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530315#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700318#ifdef WLAN_BTAMP_FEATURE
319 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700320#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700325 (strncmp(dev->name, "p2p", 3)))
326 return NOTIFY_DONE;
327
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700329 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800333 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 VOS_ASSERT(0);
335 return NOTIFY_DONE;
336 }
337
Jeff Johnson27cee452013-03-27 11:10:24 -0700338 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
339 if (NULL == pHddCtx)
340 {
341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
342 VOS_ASSERT(0);
343 return NOTIFY_DONE;
344 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800345 if (pHddCtx->isLogpInProgress)
346 return NOTIFY_DONE;
347
Jeff Johnson27cee452013-03-27 11:10:24 -0700348
349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
350 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351
352 switch (state) {
353 case NETDEV_REGISTER:
354 break;
355
356 case NETDEV_UNREGISTER:
357 break;
358
359 case NETDEV_UP:
360 break;
361
362 case NETDEV_DOWN:
363 break;
364
365 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700366 if(TRUE == pAdapter->isLinkUpSvcNeeded)
367 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 break;
369
370 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530371 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530372 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530373 {
374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
375 "%s: Timeout occurred while waiting for abortscan %ld",
376 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378 else
379 {
380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530381 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 }
383#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 status = WLANBAP_StopAmp();
386 if(VOS_STATUS_SUCCESS != status )
387 {
388 pHddCtx->isAmpAllowed = VOS_TRUE;
389 hddLog(VOS_TRACE_LEVEL_FATAL,
390 "%s: Failed to stop AMP", __func__);
391 }
392 else
393 {
394 //a state m/c implementation in PAL is TBD to avoid this delay
395 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700396 if ( pHddCtx->isAmpAllowed )
397 {
398 WLANBAP_DeregisterFromHCI();
399 pHddCtx->isAmpAllowed = VOS_FALSE;
400 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 }
402#endif //WLAN_BTAMP_FEATURE
403 break;
404
405 default:
406 break;
407 }
408
409 return NOTIFY_DONE;
410}
411
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530412static int hdd_netdev_notifier_call(struct notifier_block * nb,
413 unsigned long state,
414 void *ndev)
415{
416 int ret;
417 vos_ssr_protect(__func__);
418 ret = __hdd_netdev_notifier_call( nb, state, ndev);
419 vos_ssr_unprotect(__func__);
420 return ret;
421}
422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423struct notifier_block hdd_netdev_notifier = {
424 .notifier_call = hdd_netdev_notifier_call,
425};
426
427/*---------------------------------------------------------------------------
428 * Function definitions
429 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700430void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
431void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700432//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700433static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700434#ifndef MODULE
435/* current con_mode - used only for statically linked driver
436 * con_mode is changed by userspace to indicate a mode change which will
437 * result in calling the module exit and init functions. The module
438 * exit function will clean up based on the value of con_mode prior to it
439 * being changed by userspace. So curr_con_mode records the current con_mode
440 * for exit when con_mode becomes the next mode for init
441 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700442static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700443#endif
444
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530445#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
446/**
447 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
448 * @hdd_ctx: hdd global context
449 *
450 * Return: none
451 */
452static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
453{
454 uint8_t i;
455
456 mutex_init(&hdd_ctx->op_ctx.op_lock);
457 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
458 {
459 hdd_ctx->op_ctx.op_table[i].request_id = 0;
460 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
461 }
462}
463#else
464static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
465{
466}
467#endif
468
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800469/**---------------------------------------------------------------------------
470
471 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
472
473 Called immediately after the cfg.ini is read in order to configure
474 the desired trace levels.
475
476 \param - moduleId - module whose trace level is being configured
477 \param - bitmask - bitmask of log levels to be enabled
478
479 \return - void
480
481 --------------------------------------------------------------------------*/
482static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
483{
484 wpt_tracelevel level;
485
486 /* if the bitmask is the default value, then a bitmask was not
487 specified in cfg.ini, so leave the logging level alone (it
488 will remain at the "compiled in" default value) */
489 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
490 {
491 return;
492 }
493
494 /* a mask was specified. start by disabling all logging */
495 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
496
497 /* now cycle through the bitmask until all "set" bits are serviced */
498 level = VOS_TRACE_LEVEL_FATAL;
499 while (0 != bitmask)
500 {
501 if (bitmask & 1)
502 {
503 vos_trace_setValue(moduleId, level, 1);
504 }
505 level++;
506 bitmask >>= 1;
507 }
508}
509
510
Jeff Johnson295189b2012-06-20 16:38:30 -0700511/**---------------------------------------------------------------------------
512
513 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
514
515 Called immediately after the cfg.ini is read in order to configure
516 the desired trace levels in the WDI.
517
518 \param - moduleId - module whose trace level is being configured
519 \param - bitmask - bitmask of log levels to be enabled
520
521 \return - void
522
523 --------------------------------------------------------------------------*/
524static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
525{
526 wpt_tracelevel level;
527
528 /* if the bitmask is the default value, then a bitmask was not
529 specified in cfg.ini, so leave the logging level alone (it
530 will remain at the "compiled in" default value) */
531 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
532 {
533 return;
534 }
535
536 /* a mask was specified. start by disabling all logging */
537 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
538
539 /* now cycle through the bitmask until all "set" bits are serviced */
540 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
541 while (0 != bitmask)
542 {
543 if (bitmask & 1)
544 {
545 wpalTraceSetLevel(moduleId, level, 1);
546 }
547 level++;
548 bitmask >>= 1;
549 }
550}
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530552/*
553 * FUNCTION: wlan_hdd_validate_context
554 * This function is used to check the HDD context
555 */
556int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
557{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530558
559 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530562 "%s: HDD context is Null", __func__);
563 return -ENODEV;
564 }
565
566 if (pHddCtx->isLogpInProgress)
567 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530569 "%s: LOGP %s. Ignore!!", __func__,
570 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
571 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530572 return -EAGAIN;
573 }
574
Mihir Shete18156292014-03-11 15:38:30 +0530575 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530576 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530578 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
579 return -EAGAIN;
580 }
581 return 0;
582}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700583#ifdef CONFIG_ENABLE_LINUX_REG
584void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
585{
586 hdd_adapter_t *pAdapter = NULL;
587 hdd_station_ctx_t *pHddStaCtx = NULL;
588 eCsrPhyMode phyMode;
589 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530590
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700591 if (NULL == pHddCtx)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "HDD Context is null !!");
595 return ;
596 }
597
598 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
599 if (NULL == pAdapter)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
602 "pAdapter is null !!");
603 return ;
604 }
605
606 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
607 if (NULL == pHddStaCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
610 "pHddStaCtx is null !!");
611 return ;
612 }
613
614 cfg_param = pHddCtx->cfg_ini;
615 if (NULL == cfg_param)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
618 "cfg_params not available !!");
619 return ;
620 }
621
622 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
623
624 if (!pHddCtx->isVHT80Allowed)
625 {
626 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
627 (eCSR_DOT11_MODE_11ac == phyMode) ||
628 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
631 "Setting phymode to 11n!!");
632 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
633 }
634 }
635 else
636 {
637 /*New country Supports 11ac as well resetting value back from .ini*/
638 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
639 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
640 return ;
641 }
642
643 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
644 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
645 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
646 {
647 VOS_STATUS vosStatus;
648
649 // need to issue a disconnect to CSR.
650 INIT_COMPLETION(pAdapter->disconnect_comp_var);
651 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
652 pAdapter->sessionId,
653 eCSR_DISCONNECT_REASON_UNSPECIFIED );
654
655 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 {
657 long ret;
658
659 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530661 if (0 >= ret)
662 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
663 ret);
664 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700665
666 }
667}
668#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
670{
671 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
672 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
673 hdd_config_t *cfg_param;
674 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530675 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530676
677 if (NULL == pHddCtx)
678 {
679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
680 "HDD Context is null !!");
681 return ;
682 }
683
684 cfg_param = pHddCtx->cfg_ini;
685
686 if (NULL == cfg_param)
687 {
688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
689 "cfg_params not available !!");
690 return ;
691 }
692
693 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
694
695 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
696 {
697 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
698 (eCSR_DOT11_MODE_11ac == phyMode) ||
699 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
700 {
701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
702 "Setting phymode to 11n!!");
703 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
704 }
705 }
706 else
707 {
708 /*New country Supports 11ac as well resetting value back from .ini*/
709 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
710 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
711 return ;
712 }
713
714 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
715 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
716 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
717 {
718 VOS_STATUS vosStatus;
719
720 // need to issue a disconnect to CSR.
721 INIT_COMPLETION(pAdapter->disconnect_comp_var);
722 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
723 pAdapter->sessionId,
724 eCSR_DISCONNECT_REASON_UNSPECIFIED );
725
726 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530727 {
728 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530730 if (ret <= 0)
731 {
732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 "wait on disconnect_comp_var is failed %ld", ret);
734 }
735 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530736
737 }
738}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700739#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530740
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700741void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
742{
743 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
744 hdd_config_t *cfg_param;
745
746 if (NULL == pHddCtx)
747 {
748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
749 "HDD Context is null !!");
750 return ;
751 }
752
753 cfg_param = pHddCtx->cfg_ini;
754
755 if (NULL == cfg_param)
756 {
757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
758 "cfg_params not available !!");
759 return ;
760 }
761
Agarwal Ashish738843c2014-09-25 12:27:56 +0530762 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
763 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700764 {
765 /*New country doesn't support DFS */
766 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
767 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530768 else
769 {
770 /* New country Supports DFS as well resetting value back from .ini */
771 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
772 cfg_param->enableDFSChnlScan);
773 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700774
775}
776
Abhishek Singh00b71972016-01-07 10:51:04 +0530777#ifdef WLAN_FEATURE_RMC
778static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
779{
780 tANI_U8 *inPtr = pValue;
781 int tempInt;
782 int v = 0;
783 char buf[32];
784 *pRmcEnable = 0;
785
786 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
787 /*no argument after the command*/
788 if (NULL == inPtr)
789 {
790 return 0;
791 }
792
793 /*no space after the command*/
794 else if (SPACE_ASCII_VALUE != *inPtr)
795 {
796 return 0;
797 }
798
799 /*removing empty spaces*/
800 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
801
802 /*no argument followed by spaces*/
803 if ('\0' == *inPtr)
804 {
805 return 0;
806 }
807
808 /* getting the first argument which enables or disables RMC
809 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530810 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530811 v = kstrtos32(buf, 10, &tempInt);
812 if ( v < 0)
813 {
814 return -EINVAL;
815 }
816
817 *pRmcEnable = tempInt;
818
819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
820 "ucRmcEnable: %d", *pRmcEnable);
821
822 return 0;
823}
824
825/* Function header left blank Intentionally */
826static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
827 tANI_U32 *pActionPeriod)
828{
829 tANI_U8 *inPtr = pValue;
830 int tempInt;
831 int v = 0;
832 char buf[32];
833 *pActionPeriod = 0;
834
835 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
836 /*no argument after the command*/
837 if (NULL == inPtr)
838 {
839 return -EINVAL;
840 }
841
842 /*no space after the command*/
843 else if (SPACE_ASCII_VALUE != *inPtr)
844 {
845 return -EINVAL;
846 }
847
848 /*removing empty spaces*/
849 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
850
851 /*no argument followed by spaces*/
852 if ('\0' == *inPtr)
853 {
854 return 0;
855 }
856
857 /* getting the first argument which enables or disables RMC
858 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530859 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530860 v = kstrtos32(buf, 10, &tempInt);
861 if ( v < 0)
862 {
863 return -EINVAL;
864 }
865
866 /* Range checking for passed paramter */
867 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
868 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
869 {
870 return -EINVAL;
871 }
872
873 *pActionPeriod = tempInt;
874
875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
876 "uActionPeriod: %d", *pActionPeriod);
877
878 return 0;
879}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530880
881/**
882 * hdd_set_vowifi_mode() - Process VOWIFI command.
883 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530884 * @enable: Value to be sent as a part of the VOWIFI command
885 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530886 * Invoke the SME api if station is connected in 2.4 GHz band.
887 * Also start split scan if VOWIFIMODE and dynamic split scan
888 * both are enabled.
889
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530890 * Return: void
891 */
892void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
893{
894 tANI_U8 sta_chan;
895
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530896 if (!hdd_ctx->cfg_ini) {
897 hddLog(LOGE, "cfg_ini got NULL");
898 return;
899 }
900
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530901 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
902
Dundi Ravitejae110a042018-04-18 13:11:37 +0530903 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530904 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530905 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
907 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530908
909 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
910 hdd_ctx->is_vowifi_enabled = true;
911 hdd_ctx->issplitscan_enabled = TRUE;
912 sme_enable_disable_split_scan(hdd_ctx->hHal,
913 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
914 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
915 } else {
916 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530917 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530918}
Abhishek Singh00b71972016-01-07 10:51:04 +0530919
920/* Function header left blank Intentionally */
921static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
922 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
923{
924 tANI_U8 *inPtr = pValue;
925 int tempInt;
926 int v = 0;
927 char buf[32];
928 *pRate = 0;
929 *pTxFlags = 0;
930
931 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
932 /*no argument after the command*/
933 if (NULL == inPtr)
934 {
935 return -EINVAL;
936 }
937
938 /*no space after the command*/
939 else if (SPACE_ASCII_VALUE != *inPtr)
940 {
941 return -EINVAL;
942 }
943
944 /*removing empty spaces*/
945 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
946
947 /*no argument followed by spaces*/
948 if ('\0' == *inPtr)
949 {
950 return 0;
951 }
952
953 /*
954 * getting the first argument which sets multicast rate.
955 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530956 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530957 v = kstrtos32(buf, 10, &tempInt);
958 if ( v < 0)
959 {
960 return -EINVAL;
961 }
962
963 /*
964 * Validate the multicast rate.
965 */
966 switch (tempInt)
967 {
968 default:
969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
970 "Unsupported rate: %d", tempInt);
971 return -EINVAL;
972 case 0:
973 case 6:
974 case 9:
975 case 12:
976 case 18:
977 case 24:
978 case 36:
979 case 48:
980 case 54:
981 *pTxFlags = eHAL_TX_RATE_LEGACY;
982 *pRate = tempInt * 10;
983 break;
984 case 65:
985 *pTxFlags = eHAL_TX_RATE_HT20;
986 *pRate = tempInt * 10;
987 break;
988 case 72:
989 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
990 *pRate = 722; /* fractional rate 72.2 Mbps */
991 break;
992 }
993
994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
995 "Rate: %d", *pRate);
996
997 return 0;
998}
999
1000/**---------------------------------------------------------------------------
1001
1002 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
1003 Peer Info request
1004
1005 This is an asynchronous callback function from SME when the peer info
1006 is received
1007
1008 \pUserData -> Adapter private data
1009 \pPeerInfoRsp -> Peer info response
1010
1011 \return - 0 for success non-zero for failure
1012 --------------------------------------------------------------------------*/
1013static void
1014hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1015{
1016 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1017 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1018 hdd_station_ctx_t *pStaCtx;
1019 v_U8_t i;
1020
1021 /*Sanity check*/
1022 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1023 {
1024 hddLog(LOGE,
1025 FL("invalid adapter or adapter has invalid magic"));
1026 return;
1027 }
1028
1029 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1030 if (NULL != pStaCtx && NULL != pPeerInfo &&
1031 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1032 {
1033 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1034 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1035
1036 /* Paranoia check */
1037 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1038 {
1039 for (i = 0; i < pPeerInfo->numPeers; i++)
1040 {
1041 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1042 &pPeerInfo->peerInfoParams[i],
1043 sizeof(hdd_ibss_peer_info_params_t));
1044 }
1045 hddLog(LOG1,
1046 FL("Peer Info copied in HDD"));
1047 }
1048 else
1049 {
1050 hddLog(LOGE,
1051 FL(" Number of peers %d returned is more than limit %d"),
1052 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1053 }
1054 }
1055 else
1056 {
1057 hddLog(LOG1,
1058 FL("peerInfo returned is NULL"));
1059 }
1060
1061 complete(&pAdapter->ibss_peer_info_comp);
1062}
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1067
1068 Request function to get IBSS peer info from lower layers
1069
1070 \pAdapter -> Adapter context
1071
1072 \return - 0 for success non-zero for failure
1073 --------------------------------------------------------------------------*/
1074static
1075VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1076{
1077 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1078 long status;
1079 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1080
1081 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1082
1083 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1084 hdd_cfg80211_get_ibss_peer_info_cb,
1085 VOS_TRUE, 0xFF);
1086
1087 if (VOS_STATUS_SUCCESS == retStatus)
1088 {
1089 status = wait_for_completion_interruptible_timeout
1090 (&pAdapter->ibss_peer_info_comp,
1091 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1092
1093 /* status will be 0 if timed out */
1094 if (status <= 0)
1095 {
1096 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1097 __func__, status);
1098 retStatus = VOS_STATUS_E_FAILURE;
1099 return retStatus;
1100 }
1101 }
1102 else
1103 {
1104 hddLog(VOS_TRACE_LEVEL_WARN,
1105 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1106 }
1107
1108 return retStatus;
1109}
1110
1111/**---------------------------------------------------------------------------
1112
1113 \brief hdd_cfg80211_get_ibss_peer_info() -
1114
1115 Request function to get IBSS peer info from lower layers
1116
1117 \pAdapter -> Adapter context
1118 \staIdx -> Sta index for which the peer info is requested
1119
1120 \return - 0 for success non-zero for failure
1121 --------------------------------------------------------------------------*/
1122static VOS_STATUS
1123hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1124{
1125 long status;
1126 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1127 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1128
1129 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1130
1131 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1132 hdd_cfg80211_get_ibss_peer_info_cb,
1133 VOS_FALSE, staIdx);
1134
1135 if (VOS_STATUS_SUCCESS == retStatus)
1136 {
1137 status = wait_for_completion_interruptible_timeout
1138 (&pAdapter->ibss_peer_info_comp,
1139 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1140
1141 /* status = 0 on timeout */
1142 if (status <= 0)
1143 {
1144 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1145 __func__, status);
1146 retStatus = VOS_STATUS_E_FAILURE;
1147 return retStatus;
1148 }
1149 }
1150 else
1151 {
1152 hddLog(VOS_TRACE_LEVEL_WARN,
1153 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1154 }
1155
1156 return retStatus;
1157}
1158
1159/* Function header left blank Intentionally */
1160VOS_STATUS
1161hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1162{
1163 tANI_U8 *inPtr = pValue;
1164 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1165
1166 /*no argument after the command*/
1167 if (NULL == inPtr)
1168 {
1169 return VOS_STATUS_E_FAILURE;;
1170 }
1171
1172 /*no space after the command*/
1173 else if (SPACE_ASCII_VALUE != *inPtr)
1174 {
1175 return VOS_STATUS_E_FAILURE;;
1176 }
1177
1178 /*removing empty spaces*/
1179 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1180
1181 /*no argument followed by spaces*/
1182 if ('\0' == *inPtr)
1183 {
1184 return VOS_STATUS_E_FAILURE;;
1185 }
1186
1187 /*getting the first argument ie the peer mac address */
1188 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1189 inPtr[11] != ':' || inPtr[14] != ':')
1190 {
1191 return VOS_STATUS_E_FAILURE;;
1192 }
1193 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1194 (unsigned int *)&pPeerMacAddr->bytes[0],
1195 (unsigned int *)&pPeerMacAddr->bytes[1],
1196 (unsigned int *)&pPeerMacAddr->bytes[2],
1197 (unsigned int *)&pPeerMacAddr->bytes[3],
1198 (unsigned int *)&pPeerMacAddr->bytes[4],
1199 (unsigned int *)&pPeerMacAddr->bytes[5]);
1200
1201 /* The command buffer seems to be fine */
1202 return VOS_STATUS_SUCCESS;
1203}
1204
1205/* Function header left blank Intentionally */
1206static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1207 tANI_U32 limit)
1208{
1209 tANI_U8 len;
1210 tANI_U8 data;
1211
1212 /* skip white space */
1213 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1214 {
1215 command++;
1216 limit--;
1217 }
1218
1219 /* skip element id and element length */
1220 len = 2;
1221
1222 /* extract oui */
1223 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1224 (limit > 1))
1225 {
1226 /* Convert ASCII to decimal */
1227 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1228 ie[len++] = data;
1229 command += 2;
1230 limit -= 2;
1231 }
1232
1233 /* skip white space */
1234 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1235 {
1236 command++;
1237 limit--;
1238 }
1239
1240 /* extract data */
1241 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1242 (limit > 1))
1243 {
1244 /* Convert ASCII to decimal */
1245 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1246 ie[len++] = data;
1247 command += 2;
1248 limit -= 2;
1249 }
1250
1251 /* fill element id and element length */
1252 ie[0] = IE_EID_VENDOR;
1253 ie[1] = len - 2;
1254
1255 return len;
1256}
1257
1258static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1259{
1260 tANI_U32 ieLenPresent = 0;
1261 int left = addIeLen;
1262 v_U8_t *ptr = addIePtr;
1263 v_U8_t elem_id,elem_len;
1264
1265 while(left >= 2)
1266 {
1267 elem_id = ptr[0];
1268 elem_len = ptr[1];
1269 left -= 2;
1270 if(elem_len > left)
1271 {
1272 hddLog(LOGE,
1273 FL("****Invalid elem_len=%d left=%d*****"),
1274 elem_len,left);
1275 return 0;
1276 }
1277 if ((elem_id == IE_EID_VENDOR) &&
1278 (left >= WPA_OUI_TYPE_SIZE))
1279 {
1280 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1281 WPA_OUI_TYPE_SIZE))
1282 {
1283 ieLenPresent += elem_len + 2;
1284 return ieLenPresent;
1285 }
1286 }
1287 ieLenPresent += (elem_len + 2);
1288 left -= elem_len;
1289 ptr += (elem_len + 2);
1290 }
1291 return 0;
1292}
1293
1294#endif /* WLAN_FEATURE_RMC */
1295
Rajeev79dbe4c2013-10-05 11:03:42 +05301296#ifdef FEATURE_WLAN_BATCH_SCAN
1297
1298/**---------------------------------------------------------------------------
1299
1300 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1301 input string
1302
1303 This function extracts assigned integer from string in below format:
1304 "STRING=10" : extracts integer 10 from this string
1305
1306 \param - pInPtr Pointer to input string
1307 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1308 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1309 assigned
1310 \param - pLastArg to tell whether it is last arguement in input string or
1311 not
1312
1313 \return - NULL for failure cases
1314 pointer to next arguement in input string for success cases
1315 --------------------------------------------------------------------------*/
1316static tANI_U8 *
1317hdd_extract_assigned_int_from_str
1318(
1319 tANI_U8 *pInPtr,
1320 tANI_U8 base,
1321 tANI_U32 *pOutPtr,
1322 tANI_U8 *pLastArg
1323)
1324{
1325 int tempInt;
1326 int v = 0;
1327 char buf[32];
1328 int val = 0;
1329 *pLastArg = FALSE;
1330
1331 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1332 if (NULL == pInPtr)
1333 {
1334 return NULL;
1335 }
1336
1337 pInPtr++;
1338
1339 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1340
1341 val = sscanf(pInPtr, "%32s ", buf);
1342 if (val < 0 && val > strlen(pInPtr))
1343 {
1344 return NULL;
1345 }
1346 pInPtr += val;
1347 v = kstrtos32(buf, base, &tempInt);
1348 if (v < 0)
1349 {
1350 return NULL;
1351 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001352 if (tempInt < 0)
1353 {
1354 tempInt = 0;
1355 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301356 *pOutPtr = tempInt;
1357
1358 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1359 if (NULL == pInPtr)
1360 {
1361 *pLastArg = TRUE;
1362 return NULL;
1363 }
1364 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1365
1366 return pInPtr;
1367}
1368
1369/**---------------------------------------------------------------------------
1370
1371 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1372 input string
1373
1374 This function extracts assigned character from string in below format:
1375 "STRING=A" : extracts char 'A' from this string
1376
1377 \param - pInPtr Pointer to input string
1378 \param - pOutPtr Pointer to variable in which extracted char needs to be
1379 assigned
1380 \param - pLastArg to tell whether it is last arguement in input string or
1381 not
1382
1383 \return - NULL for failure cases
1384 pointer to next arguement in input string for success cases
1385 --------------------------------------------------------------------------*/
1386static tANI_U8 *
1387hdd_extract_assigned_char_from_str
1388(
1389 tANI_U8 *pInPtr,
1390 tANI_U8 *pOutPtr,
1391 tANI_U8 *pLastArg
1392)
1393{
1394 *pLastArg = FALSE;
1395
1396 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1397 if (NULL == pInPtr)
1398 {
1399 return NULL;
1400 }
1401
1402 pInPtr++;
1403
1404 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1405
1406 *pOutPtr = *pInPtr;
1407
1408 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1409 if (NULL == pInPtr)
1410 {
1411 *pLastArg = TRUE;
1412 return NULL;
1413 }
1414 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1415
1416 return pInPtr;
1417}
1418
1419
1420/**---------------------------------------------------------------------------
1421
1422 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1423
1424 This function parses set batch scan command in below format:
1425 WLS_BATCHING_SET <space> followed by below arguements
1426 "SCANFREQ=XX" : Optional defaults to 30 sec
1427 "MSCAN=XX" : Required number of scans to attempt to batch
1428 "BESTN=XX" : Best Network (RSSI) defaults to 16
1429 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1430 A. implies only 5 GHz , B. implies only 2.4GHz
1431 "RTT=X" : optional defaults to 0
1432 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1433 error
1434
1435 For example input commands:
1436 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1437 translated into set batch scan with following parameters:
1438 a) Frequence 60 seconds
1439 b) Batch 10 scans together
1440 c) Best RSSI to be 20
1441 d) 5GHz band only
1442 e) RTT is equal to 0
1443
1444 \param - pValue Pointer to input channel list
1445 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1446
1447 \return - 0 for success non-zero for failure
1448
1449 --------------------------------------------------------------------------*/
1450static int
1451hdd_parse_set_batchscan_command
1452(
1453 tANI_U8 *pValue,
1454 tSirSetBatchScanReq *pHddSetBatchScanReq
1455)
1456{
1457 tANI_U8 *inPtr = pValue;
1458 tANI_U8 val = 0;
1459 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301460 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001461 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301462 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1463 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1464 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001465 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301466
Rajeev79dbe4c2013-10-05 11:03:42 +05301467 /*go to space after WLS_BATCHING_SET command*/
1468 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1469 /*no argument after the command*/
1470 if (NULL == inPtr)
1471 {
1472 return -EINVAL;
1473 }
1474
1475 /*no space after the command*/
1476 else if (SPACE_ASCII_VALUE != *inPtr)
1477 {
1478 return -EINVAL;
1479 }
1480
1481 /*removing empty spaces*/
1482 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1483
1484 /*no argument followed by spaces*/
1485 if ('\0' == *inPtr)
1486 {
1487 return -EINVAL;
1488 }
1489
1490 /*check and parse SCANFREQ*/
1491 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1492 {
1493 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001494 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001495
Rajeev Kumarc933d982013-11-18 20:04:20 -08001496 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001497 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001498 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001499 }
1500
Rajeev79dbe4c2013-10-05 11:03:42 +05301501 if ( (NULL == inPtr) || (TRUE == lastArg))
1502 {
1503 return -EINVAL;
1504 }
1505 }
1506
1507 /*check and parse MSCAN*/
1508 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1509 {
1510 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001511 &nMscan, &lastArg);
1512
1513 if (0 == nMscan)
1514 {
1515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1516 "invalid MSCAN=%d", nMscan);
1517 return -EINVAL;
1518 }
1519
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 if (TRUE == lastArg)
1521 {
1522 goto done;
1523 }
1524 else if (NULL == inPtr)
1525 {
1526 return -EINVAL;
1527 }
1528 }
1529 else
1530 {
1531 return -EINVAL;
1532 }
1533
1534 /*check and parse BESTN*/
1535 if ((strncmp(inPtr, "BESTN", 5) == 0))
1536 {
1537 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001538 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001539
Rajeev Kumarc933d982013-11-18 20:04:20 -08001540 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001541 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001542 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001543 }
1544
Rajeev79dbe4c2013-10-05 11:03:42 +05301545 if (TRUE == lastArg)
1546 {
1547 goto done;
1548 }
1549 else if (NULL == inPtr)
1550 {
1551 return -EINVAL;
1552 }
1553 }
1554
1555 /*check and parse CHANNEL*/
1556 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1557 {
1558 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001559
Rajeev79dbe4c2013-10-05 11:03:42 +05301560 if (('A' == val) || ('a' == val))
1561 {
c_hpothuebf89732014-02-25 13:00:24 +05301562 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301563 }
1564 else if (('B' == val) || ('b' == val))
1565 {
c_hpothuebf89732014-02-25 13:00:24 +05301566 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301567 }
1568 else
1569 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001570 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1571 }
1572
1573 if (TRUE == lastArg)
1574 {
1575 goto done;
1576 }
1577 else if (NULL == inPtr)
1578 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301579 return -EINVAL;
1580 }
1581 }
1582
1583 /*check and parse RTT*/
1584 if ((strncmp(inPtr, "RTT", 3) == 0))
1585 {
1586 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001587 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 if (TRUE == lastArg)
1589 {
1590 goto done;
1591 }
1592 if (NULL == inPtr)
1593 {
1594 return -EINVAL;
1595 }
1596 }
1597
1598
1599done:
1600
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001601 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1602 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1603 pHddSetBatchScanReq->bestNetwork = nBestN;
1604 pHddSetBatchScanReq->rfBand = ucRfBand;
1605 pHddSetBatchScanReq->rtt = nRtt;
1606
Rajeev79dbe4c2013-10-05 11:03:42 +05301607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1608 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1609 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1610 pHddSetBatchScanReq->scanFrequency,
1611 pHddSetBatchScanReq->numberOfScansToBatch,
1612 pHddSetBatchScanReq->bestNetwork,
1613 pHddSetBatchScanReq->rfBand,
1614 pHddSetBatchScanReq->rtt);
1615
1616 return 0;
1617}/*End of hdd_parse_set_batchscan_command*/
1618
1619/**---------------------------------------------------------------------------
1620
1621 \brief hdd_set_batch_scan_req_callback () - This function is called after
1622 receiving set batch scan response from FW and it saves set batch scan
1623 response data FW to HDD context and sets the completion event on
1624 which hdd_ioctl is waiting
1625
1626 \param - callbackContext Pointer to HDD adapter
1627 \param - pRsp Pointer to set batch scan response data received from FW
1628
1629 \return - nothing
1630
1631 --------------------------------------------------------------------------*/
1632static void hdd_set_batch_scan_req_callback
1633(
1634 void *callbackContext,
1635 tSirSetBatchScanRsp *pRsp
1636)
1637{
1638 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1639 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1640
1641 /*sanity check*/
1642 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1643 {
1644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1645 "%s: Invalid pAdapter magic", __func__);
1646 VOS_ASSERT(0);
1647 return;
1648 }
1649 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1650
1651 /*save set batch scan response*/
1652 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1653
1654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1655 "Received set batch scan rsp from FW with nScansToBatch=%d",
1656 pHddSetBatchScanRsp->nScansToBatch);
1657
1658 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1659 complete(&pAdapter->hdd_set_batch_scan_req_var);
1660
1661 return;
1662}/*End of hdd_set_batch_scan_req_callback*/
1663
1664
1665/**---------------------------------------------------------------------------
1666
1667 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1668 info in hdd batch scan response queue
1669
1670 \param - pAdapter Pointer to hdd adapter
1671 \param - pAPMetaInfo Pointer to access point meta info
1672 \param - scanId scan ID of batch scan response
1673 \param - isLastAp tells whether AP is last AP in batch scan response or not
1674
1675 \return - nothing
1676
1677 --------------------------------------------------------------------------*/
1678static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1679 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1680{
1681 tHddBatchScanRsp *pHead;
1682 tHddBatchScanRsp *pNode;
1683 tHddBatchScanRsp *pPrev;
1684 tHddBatchScanRsp *pTemp;
1685 tANI_U8 ssidLen;
1686
1687 /*head of hdd batch scan response queue*/
1688 pHead = pAdapter->pBatchScanRsp;
1689
1690 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1691 if (NULL == pNode)
1692 {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1694 "%s: Could not allocate memory", __func__);
1695 VOS_ASSERT(0);
1696 return;
1697 }
1698
1699 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1700 sizeof(pNode->ApInfo.bssid));
1701 ssidLen = strlen(pApMetaInfo->ssid);
1702 if (SIR_MAX_SSID_SIZE < ssidLen)
1703 {
1704 /*invalid scan result*/
1705 vos_mem_free(pNode);
1706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1707 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1708 return;
1709 }
1710 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1711 /*null terminate ssid*/
1712 pNode->ApInfo.ssid[ssidLen] = '\0';
1713 pNode->ApInfo.ch = pApMetaInfo->ch;
1714 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1715 pNode->ApInfo.age = pApMetaInfo->timestamp;
1716 pNode->ApInfo.batchId = scanId;
1717 pNode->ApInfo.isLastAp = isLastAp;
1718
1719 pNode->pNext = NULL;
1720 if (NULL == pHead)
1721 {
1722 pAdapter->pBatchScanRsp = pNode;
1723 }
1724 else
1725 {
1726 pTemp = pHead;
1727 while (NULL != pTemp)
1728 {
1729 pPrev = pTemp;
1730 pTemp = pTemp->pNext;
1731 }
1732 pPrev->pNext = pNode;
1733 }
1734
1735 return;
1736}/*End of hdd_populate_batch_scan_rsp_queue*/
1737
1738/**---------------------------------------------------------------------------
1739
1740 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1741 receiving batch scan response indication from FW. It saves get batch scan
1742 response data in HDD batch scan response queue. This callback sets the
1743 completion event on which hdd_ioctl is waiting only after getting complete
1744 batch scan response data from FW
1745
1746 \param - callbackContext Pointer to HDD adapter
1747 \param - pRsp Pointer to get batch scan response data received from FW
1748
1749 \return - nothing
1750
1751 --------------------------------------------------------------------------*/
1752static void hdd_batch_scan_result_ind_callback
1753(
1754 void *callbackContext,
1755 void *pRsp
1756)
1757{
1758 v_BOOL_t isLastAp;
1759 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001760 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301761 tANI_U32 numberScanList;
1762 tANI_U32 nextScanListOffset;
1763 tANI_U32 nextApMetaInfoOffset;
1764 hdd_adapter_t* pAdapter;
1765 tpSirBatchScanList pScanList;
1766 tpSirBatchScanNetworkInfo pApMetaInfo;
1767 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1768 tSirSetBatchScanReq *pReq;
1769
1770 pAdapter = (hdd_adapter_t *)callbackContext;
1771 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001772 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301773 {
1774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1775 "%s: Invalid pAdapter magic", __func__);
1776 VOS_ASSERT(0);
1777 return;
1778 }
1779
1780 /*initialize locals*/
1781 pReq = &pAdapter->hddSetBatchScanReq;
1782 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1783 isLastAp = FALSE;
1784 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001785 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301786 numberScanList = 0;
1787 nextScanListOffset = 0;
1788 nextApMetaInfoOffset = 0;
1789 pScanList = NULL;
1790 pApMetaInfo = NULL;
1791
1792 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001795 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301796 isLastAp = TRUE;
1797 goto done;
1798 }
1799
1800 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "Batch scan rsp: numberScalList %d", numberScanList);
1803
1804 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "%s: numberScanList %d", __func__, numberScanList);
1808 isLastAp = TRUE;
1809 goto done;
1810 }
1811
1812 while (numberScanList)
1813 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001814 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301815 nextScanListOffset);
1816 if (NULL == pScanList)
1817 {
1818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001819 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301820 isLastAp = TRUE;
1821 goto done;
1822 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001823 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001825 "Batch scan rsp: numApMetaInfo %d scanId %d",
1826 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301827
1828 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1829 {
1830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1831 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1832 isLastAp = TRUE;
1833 goto done;
1834 }
1835
Rajeev Kumarce651e42013-10-21 18:57:15 -07001836 /*Initialize next AP meta info offset for next scan list*/
1837 nextApMetaInfoOffset = 0;
1838
Rajeev79dbe4c2013-10-05 11:03:42 +05301839 while (numApMetaInfo)
1840 {
1841 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1842 nextApMetaInfoOffset);
1843 if (NULL == pApMetaInfo)
1844 {
1845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001846 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301847 isLastAp = TRUE;
1848 goto done;
1849 }
1850 /*calculate AP age*/
1851 pApMetaInfo->timestamp =
1852 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1853
1854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001855 "%s: bssId "MAC_ADDRESS_STR
1856 " ch %d rssi %d timestamp %d", __func__,
1857 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1858 pApMetaInfo->ch, pApMetaInfo->rssi,
1859 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301860
1861 /*mark last AP in batch scan response*/
1862 if ((TRUE == pBatchScanRsp->isLastResult) &&
1863 (1 == numberScanList) && (1 == numApMetaInfo))
1864 {
1865 isLastAp = TRUE;
1866 }
1867
1868 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1869 /*store batch scan repsonse in hdd queue*/
1870 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1871 pScanList->scanId, isLastAp);
1872 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1873
1874 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1875 numApMetaInfo--;
1876 }
1877
Rajeev Kumarce651e42013-10-21 18:57:15 -07001878 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1879 + (sizeof(tSirBatchScanNetworkInfo)
1880 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301881 numberScanList--;
1882 }
1883
1884done:
1885
1886 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1887 requested from hdd_ioctl*/
1888 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1889 (TRUE == isLastAp))
1890 {
1891 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1892 complete(&pAdapter->hdd_get_batch_scan_req_var);
1893 }
1894
1895 return;
1896}/*End of hdd_batch_scan_result_ind_callback*/
1897
1898/**---------------------------------------------------------------------------
1899
1900 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1901 response as per batch scan FR request format by putting proper markers
1902
1903 \param - pDest pointer to destination buffer
1904 \param - cur_len current length
1905 \param - tot_len total remaining size which can be written to user space
1906 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1907 \param - pAdapter Pointer to HDD adapter
1908
1909 \return - ret no of characters written
1910
1911 --------------------------------------------------------------------------*/
1912static tANI_U32
1913hdd_format_batch_scan_rsp
1914(
1915 tANI_U8 *pDest,
1916 tANI_U32 cur_len,
1917 tANI_U32 tot_len,
1918 tHddBatchScanRsp *pApMetaInfo,
1919 hdd_adapter_t* pAdapter
1920)
1921{
1922 tANI_U32 ret = 0;
1923 tANI_U32 rem_len = 0;
1924 tANI_U8 temp_len = 0;
1925 tANI_U8 temp_total_len = 0;
1926 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1927 tANI_U8 *pTemp = temp;
1928
1929 /*Batch scan reponse needs to be returned to user space in
1930 following format:
1931 "scancount=X\n" where X is the number of scans in current batch
1932 batch
1933 "trunc\n" optional present if current scan truncated
1934 "bssid=XX:XX:XX:XX:XX:XX\n"
1935 "ssid=XXXX\n"
1936 "freq=X\n" frequency in Mhz
1937 "level=XX\n"
1938 "age=X\n" ms
1939 "dist=X\n" cm (-1 if not available)
1940 "errror=X\n" (-1if not available)
1941 "====\n" (end of ap marker)
1942 "####\n" (end of scan marker)
1943 "----\n" (end of results)*/
1944 /*send scan result in above format to user space based on
1945 available length*/
1946 /*The GET response may have more data than the driver can return in its
1947 buffer. In that case the buffer should be filled to the nearest complete
1948 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1949 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1950 The final buffer should end with "----\n"*/
1951
1952 /*sanity*/
1953 if (cur_len > tot_len)
1954 {
1955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1956 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1957 return 0;
1958 }
1959 else
1960 {
1961 rem_len = (tot_len - cur_len);
1962 }
1963
1964 /*end scan marker*/
1965 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1966 {
1967 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1968 pTemp += temp_len;
1969 temp_total_len += temp_len;
1970 }
1971
1972 /*bssid*/
1973 temp_len = snprintf(pTemp, sizeof(temp),
1974 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1975 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1976 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1977 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*ssid*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1983 pApMetaInfo->ApInfo.ssid);
1984 pTemp += temp_len;
1985 temp_total_len += temp_len;
1986
1987 /*freq*/
1988 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001989 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301990 pTemp += temp_len;
1991 temp_total_len += temp_len;
1992
1993 /*level*/
1994 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1995 pApMetaInfo->ApInfo.rssi);
1996 pTemp += temp_len;
1997 temp_total_len += temp_len;
1998
1999 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07002000 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05302001 pApMetaInfo->ApInfo.age);
2002 pTemp += temp_len;
2003 temp_total_len += temp_len;
2004
2005 /*dist*/
2006 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2007 pTemp += temp_len;
2008 temp_total_len += temp_len;
2009
2010 /*error*/
2011 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2012 pTemp += temp_len;
2013 temp_total_len += temp_len;
2014
2015 /*end AP marker*/
2016 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2017 pTemp += temp_len;
2018 temp_total_len += temp_len;
2019
2020 /*last AP in batch scan response*/
2021 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2022 {
2023 /*end scan marker*/
2024 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2025 pTemp += temp_len;
2026 temp_total_len += temp_len;
2027
2028 /*end batch scan result marker*/
2029 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2030 pTemp += temp_len;
2031 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002032
Rajeev79dbe4c2013-10-05 11:03:42 +05302033 }
2034
2035 if (temp_total_len < rem_len)
2036 {
2037 ret = temp_total_len + 1;
2038 strlcpy(pDest, temp, ret);
2039 pAdapter->isTruncated = FALSE;
2040 }
2041 else
2042 {
2043 pAdapter->isTruncated = TRUE;
2044 if (rem_len >= strlen("%%%%"))
2045 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002046 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302047 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002048 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302049 {
2050 ret = 0;
2051 }
2052 }
2053
2054 return ret;
2055
2056}/*End of hdd_format_batch_scan_rsp*/
2057
2058/**---------------------------------------------------------------------------
2059
2060 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2061 buffer starting with head of hdd batch scan response queue
2062
2063 \param - pAdapter Pointer to HDD adapter
2064 \param - pDest Pointer to user data buffer
2065 \param - cur_len current offset in user buffer
2066 \param - rem_len remaining no of bytes in user buffer
2067
2068 \return - number of bytes written in user buffer
2069
2070 --------------------------------------------------------------------------*/
2071
2072tANI_U32 hdd_populate_user_batch_scan_rsp
2073(
2074 hdd_adapter_t* pAdapter,
2075 tANI_U8 *pDest,
2076 tANI_U32 cur_len,
2077 tANI_U32 rem_len
2078)
2079{
2080 tHddBatchScanRsp *pHead;
2081 tHddBatchScanRsp *pPrev;
2082 tANI_U32 len;
2083
Rajeev79dbe4c2013-10-05 11:03:42 +05302084 pAdapter->isTruncated = FALSE;
2085
2086 /*head of hdd batch scan response queue*/
2087 pHead = pAdapter->pBatchScanRsp;
2088 while (pHead)
2089 {
2090 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2091 pAdapter);
2092 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002093 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302094 cur_len += len;
2095 if(TRUE == pAdapter->isTruncated)
2096 {
2097 /*result is truncated return rest of scan rsp in next req*/
2098 cur_len = rem_len;
2099 break;
2100 }
2101 pPrev = pHead;
2102 pHead = pHead->pNext;
2103 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002104 if (TRUE == pPrev->ApInfo.isLastAp)
2105 {
2106 pAdapter->prev_batch_id = 0;
2107 }
2108 else
2109 {
2110 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2111 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302112 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002113 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302114 }
2115
2116 return cur_len;
2117}/*End of hdd_populate_user_batch_scan_rsp*/
2118
2119/**---------------------------------------------------------------------------
2120
2121 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2122 scan response data from HDD queue to user space
2123 It does following in detail:
2124 a) if HDD has enough data in its queue then it 1st copies data to user
2125 space and then send get batch scan indication message to FW. In this
2126 case it does not wait on any event and batch scan response data will
2127 be populated in HDD response queue in MC thread context after receiving
2128 indication from FW
2129 b) else send get batch scan indication message to FW and wait on an event
2130 which will be set once HDD receives complete batch scan response from
2131 FW and then this function returns batch scan response to user space
2132
2133 \param - pAdapter Pointer to HDD adapter
2134 \param - pPrivData Pointer to priv_data
2135
2136 \return - 0 for success -EFAULT for failure
2137
2138 --------------------------------------------------------------------------*/
2139
2140int hdd_return_batch_scan_rsp_to_user
2141(
2142 hdd_adapter_t* pAdapter,
2143 hdd_priv_data_t *pPrivData,
2144 tANI_U8 *command
2145)
2146{
2147 tANI_U8 *pDest;
2148 tANI_U32 count = 0;
2149 tANI_U32 len = 0;
2150 tANI_U32 cur_len = 0;
2151 tANI_U32 rem_len = 0;
2152 eHalStatus halStatus;
2153 unsigned long rc;
2154 tSirTriggerBatchScanResultInd *pReq;
2155
2156 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2157 pReq->param = 0;/*batch scan client*/
2158 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2159 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2160
2161 cur_len = pPrivData->used_len;
2162 if (pPrivData->total_len > pPrivData->used_len)
2163 {
2164 rem_len = pPrivData->total_len - pPrivData->used_len;
2165 }
2166 else
2167 {
2168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2169 "%s: Invalid user data buffer total_len %d used_len %d",
2170 __func__, pPrivData->total_len, pPrivData->used_len);
2171 return -EFAULT;
2172 }
2173
2174 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2175 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2176 cur_len, rem_len);
2177 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2178
2179 /*enough scan result available in cache to return to user space or
2180 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002181 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302182 {
2183 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2184 halStatus = sme_TriggerBatchScanResultInd(
2185 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2186 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2187 pAdapter);
2188 if ( eHAL_STATUS_SUCCESS == halStatus )
2189 {
2190 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2191 {
2192 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2193 rc = wait_for_completion_timeout(
2194 &pAdapter->hdd_get_batch_scan_req_var,
2195 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302196 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 {
2198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302199 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2200 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302201 return -EFAULT;
2202 }
2203 }
2204
2205 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002206 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302207 pDest += len;
2208 cur_len += len;
2209
2210 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2211 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2212 cur_len, rem_len);
2213 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2214
2215 count = 0;
2216 len = (len - pPrivData->used_len);
2217 pDest = (command + pPrivData->used_len);
2218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002219 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302220 while(count < len)
2221 {
2222 printk("%c", *(pDest + count));
2223 count++;
2224 }
2225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2226 "%s: copy %d data to user buffer", __func__, len);
2227 if (copy_to_user(pPrivData->buf, pDest, len))
2228 {
2229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2230 "%s: failed to copy data to user buffer", __func__);
2231 return -EFAULT;
2232 }
2233 }
2234 else
2235 {
2236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2237 "sme_GetBatchScanScan returned failure halStatus %d",
2238 halStatus);
2239 return -EINVAL;
2240 }
2241 }
2242 else
2243 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 count = 0;
2245 len = (len - pPrivData->used_len);
2246 pDest = (command + pPrivData->used_len);
2247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002248 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302249 while(count < len)
2250 {
2251 printk("%c", *(pDest + count));
2252 count++;
2253 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2255 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302256 if (copy_to_user(pPrivData->buf, pDest, len))
2257 {
2258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2259 "%s: failed to copy data to user buffer", __func__);
2260 return -EFAULT;
2261 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302262 }
2263
2264 return 0;
2265} /*End of hdd_return_batch_scan_rsp_to_user*/
2266
Rajeev Kumar8b373292014-01-08 20:36:55 -08002267/**---------------------------------------------------------------------------
2268
2269 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2270 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2271 WLS_BATCHING VERSION
2272 WLS_BATCHING SET
2273 WLS_BATCHING GET
2274 WLS_BATCHING STOP
2275
2276 \param - pAdapter Pointer to HDD adapter
2277 \param - pPrivdata Pointer to priv_data
2278 \param - command Pointer to command
2279
2280 \return - 0 for success -EFAULT for failure
2281
2282 --------------------------------------------------------------------------*/
2283
2284int hdd_handle_batch_scan_ioctl
2285(
2286 hdd_adapter_t *pAdapter,
2287 hdd_priv_data_t *pPrivdata,
2288 tANI_U8 *command
2289)
2290{
2291 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002292 hdd_context_t *pHddCtx;
2293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302294 ENTER();
2295
Yue Mae36e3552014-03-05 17:06:20 -08002296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2297 ret = wlan_hdd_validate_context(pHddCtx);
2298 if (ret)
2299 {
Yue Mae36e3552014-03-05 17:06:20 -08002300 goto exit;
2301 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002302
2303 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2304 {
2305 char extra[32];
2306 tANI_U8 len = 0;
2307 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2308
2309 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2310 {
2311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2312 "%s: Batch scan feature is not supported by FW", __func__);
2313 ret = -EINVAL;
2314 goto exit;
2315 }
2316
2317 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2318 version);
2319 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2320 {
2321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2322 "%s: failed to copy data to user buffer", __func__);
2323 ret = -EFAULT;
2324 goto exit;
2325 }
2326 ret = HDD_BATCH_SCAN_VERSION;
2327 }
2328 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2329 {
2330 int status;
2331 tANI_U8 *value = (command + 16);
2332 eHalStatus halStatus;
2333 unsigned long rc;
2334 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2335 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2336
2337 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2338 {
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2340 "%s: Batch scan feature is not supported by FW", __func__);
2341 ret = -EINVAL;
2342 goto exit;
2343 }
2344
2345 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2346 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2347 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2348 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2349 {
2350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302351 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002352 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302353 hdd_device_modetoString(pAdapter->device_mode),
2354 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002355 ret = -EINVAL;
2356 goto exit;
2357 }
2358
2359 status = hdd_parse_set_batchscan_command(value, pReq);
2360 if (status)
2361 {
2362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2363 "Invalid WLS_BATCHING SET command");
2364 ret = -EINVAL;
2365 goto exit;
2366 }
2367
2368
2369 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2370 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2371 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2372 pAdapter);
2373
2374 if ( eHAL_STATUS_SUCCESS == halStatus )
2375 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302376 char extra[32];
2377 tANI_U8 len = 0;
2378 tANI_U8 mScan = 0;
2379
Rajeev Kumar8b373292014-01-08 20:36:55 -08002380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2381 "sme_SetBatchScanReq returned success halStatus %d",
2382 halStatus);
2383 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2384 {
2385 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2386 rc = wait_for_completion_timeout(
2387 &pAdapter->hdd_set_batch_scan_req_var,
2388 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2389 if (0 == rc)
2390 {
2391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2392 "%s: Timeout waiting for set batch scan to complete",
2393 __func__);
2394 ret = -EINVAL;
2395 goto exit;
2396 }
2397 }
2398 if ( !pRsp->nScansToBatch )
2399 {
2400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2401 "%s: Received set batch scan failure response from FW",
2402 __func__);
2403 ret = -EINVAL;
2404 goto exit;
2405 }
2406 /*As per the Batch Scan Framework API we should return the MIN of
2407 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302408 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002409
2410 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2411
2412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302414 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2415 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2416 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy MSCAN value to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002423 }
2424 else
2425 {
2426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "sme_SetBatchScanReq returned failure halStatus %d",
2428 halStatus);
2429 ret = -EINVAL;
2430 goto exit;
2431 }
2432 }
2433 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2434 {
2435 eHalStatus halStatus;
2436 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2437 pInd->param = 0;
2438
2439 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2440 {
2441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2442 "%s: Batch scan feature is not supported by FW", __func__);
2443 ret = -EINVAL;
2444 goto exit;
2445 }
2446
2447 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2448 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002450 "Batch scan is not yet enabled batch scan state %d",
2451 pAdapter->batchScanState);
2452 ret = -EINVAL;
2453 goto exit;
2454 }
2455
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002456 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2457 hdd_deinit_batch_scan(pAdapter);
2458 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2459
Rajeev Kumar8b373292014-01-08 20:36:55 -08002460 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2461
2462 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2463 pAdapter->sessionId);
2464 if ( eHAL_STATUS_SUCCESS == halStatus )
2465 {
2466 ret = 0;
2467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2468 "sme_StopBatchScanInd returned success halStatus %d",
2469 halStatus);
2470 }
2471 else
2472 {
2473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "sme_StopBatchScanInd returned failure halStatus %d",
2475 halStatus);
2476 ret = -EINVAL;
2477 goto exit;
2478 }
2479 }
2480 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2481 {
2482 tANI_U32 remain_len;
2483
2484 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2485 {
2486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2487 "%s: Batch scan feature is not supported by FW", __func__);
2488 ret = -EINVAL;
2489 goto exit;
2490 }
2491
2492 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2493 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002495 "Batch scan is not yet enabled could not return results"
2496 "Batch Scan state %d",
2497 pAdapter->batchScanState);
2498 ret = -EINVAL;
2499 goto exit;
2500 }
2501
2502 pPrivdata->used_len = 16;
2503 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2504 if (remain_len < pPrivdata->total_len)
2505 {
2506 /*Clear previous batch scan response data if any*/
2507 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2508 }
2509 else
2510 {
2511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2512 "Invalid total length from user space can't fetch batch"
2513 " scan response total_len %d used_len %d remain len %d",
2514 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2515 ret = -EINVAL;
2516 goto exit;
2517 }
2518 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2519 }
2520
2521exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302522 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002523 return ret;
2524}
2525
2526
Rajeev79dbe4c2013-10-05 11:03:42 +05302527#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2528
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302529#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2530/**
2531 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2532 * to Handoff request
2533 * @handoffInfo: Pointer to Handoff request
2534 * @src: enum of handoff_src
2535 * Return: None
2536 */
2537#ifndef QCA_WIFI_ISOC
2538static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2539 *handoffInfo, handoff_src src)
2540{
2541 handoffInfo->src = src;
2542}
2543#else
2544static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2545 *handoffInfo, handoff_src src)
2546{
2547}
2548#endif
2549
2550/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552 *
2553 * @pAdapter: Adapter upon which the command was received
2554 * @bssid: BSSID with which to reassociate
2555 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302556 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302557 *
2558 * Return: 0 for success non-zero for failure
2559 */
2560#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302561int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302562 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302563{
2564 hdd_station_ctx_t *pHddStaCtx;
2565 tCsrHandoffRequest handoffInfo;
2566 hdd_context_t *pHddCtx = NULL;
2567 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2568
2569 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2570
2571 /* if not associated, no need to proceed with reassoc */
2572 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2573 hddLog(LOG1, FL("Not associated"));
2574 return -EINVAL;
2575 }
2576
2577 /* if the target bssid is same as currently associated AP,
2578 then no need to proceed with reassoc */
2579 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2580 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2581 return -EINVAL;
2582 }
2583
2584 /* Check channel number is a valid channel number */
2585 if (VOS_STATUS_SUCCESS !=
2586 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2587 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2588 return -EINVAL;
2589 }
2590
2591 /* Proceed with reassoc */
2592 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302593 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302594 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2595 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2596 return 0;
2597}
2598#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302599int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302600 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302601{
2602 return -EPERM;
2603}
2604#endif
2605
2606/**
2607 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2608 * This function parses the v1 REASSOC command with the format
2609 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2610 * Hex-ASCII representation of the BSSID and CH is the ASCII
2611 * representation of the channel. For example
2612 * REASSOC 00:0a:0b:11:22:33 48
2613 *
2614 * @pAdapter: Adapter upon which the command was received
2615 * @command: ASCII text command that was received
2616 *
2617 * Return: 0 for success non-zero for failure
2618 */
2619static int
2620hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2621{
2622 tANI_U8 channel = 0;
2623 tSirMacAddr bssid;
2624 int ret;
2625
2626 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2627 if (ret)
2628 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2629 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302630 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302631
2632 return ret;
2633}
2634
2635/**
2636 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2637 * This function parses the v2 REASSOC command with the format
2638 * REASSOC <android_wifi_reassoc_params>
2639 *
2640 * @pAdapter: Adapter upon which the command was received
2641 * @command: command that was received, ASCII command followed
2642 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302644 *
2645 * Return: 0 for success non-zero for failure
2646 */
2647static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302648hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2649 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302650{
2651 struct android_wifi_reassoc_params params;
2652 tSirMacAddr bssid;
2653 int ret;
2654
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302655 if (total_len < sizeof(params) + 8) {
2656 hddLog(LOGE, FL("Invalid command length"));
2657 return -EINVAL;
2658 }
2659
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302660 /* The params are located after "REASSOC " */
2661 memcpy(&params, command + 8, sizeof(params));
2662
2663 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2664 hddLog(LOGE, FL("MAC address parsing failed"));
2665 ret = -EINVAL;
2666 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302667 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302668 }
2669 return ret;
2670}
2671
2672/**
2673 * hdd_parse_reassoc() - parse the REASSOC command
2674 * There are two different versions of the REASSOC command.Version 1
2675 * of the command contains a parameter list that is ASCII characters
2676 * whereas version 2 contains a combination of ASCII and binary
2677 * payload. Determine if a version 1 or a version 2 command is being
2678 * parsed by examining the parameters, and then dispatch the parser
2679 * that is appropriate for the command.
2680 *
2681 * @pAdapter: Adapter upon which the command was received
2682 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302683 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302684 *
2685 * Return: 0 for success non-zero for failure
2686 */
2687static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302688hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302689{
2690 int ret;
2691
2692 /*
2693 * both versions start with "REASSOC"
2694 * v1 has a bssid and channel # as an ASCII string
2695 * REASSOC xx:xx:xx:xx:xx:xx CH
2696 * v2 has a C struct
2697 * REASSOC <binary c struct>
2698 *
2699 * The first field in the v2 struct is also the bssid in ASCII.
2700 * But in the case of a v2 message the BSSID is NUL-terminated.
2701 * Hence we can peek at that offset to see if this is V1 or V2
2702 * REASSOC xx:xx:xx:xx:xx:xx*
2703 * 1111111111222222
2704 * 01234567890123456789012345
2705 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302706
2707 if (total_len < 26) {
2708 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2709 return -EINVAL;
2710 }
2711
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302712 if (command[25])
2713 ret = hdd_parse_reassoc_v1(pAdapter, command);
2714 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302715 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302716
2717 return ret;
2718}
2719#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2720
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302721struct bcn_miss_rate_priv {
2722 int bcn_miss_rate;
2723};
2724
2725/**
2726 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2727 * rate from firmware
2728 * @status: Status of get beacon miss rate operation
2729 * @bcnMissRate: Beacon miss rate
2730 * @context: Context passed while registering callback
2731 *
2732 * This function is invoked by WDA layer on receiving
2733 * WDI_GET_BCN_MISS_RATE_RSP
2734 *
2735 * Return: None
2736 */
2737static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2738 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302739{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302740 struct hdd_request *request;
2741 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302742
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302743 request = hdd_request_get(context);
2744 if (!request) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2746 return;
2747 }
c_hpothu92367912014-05-01 15:18:17 +05302748
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302749 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302750
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302751 if (VOS_STATUS_SUCCESS == status)
2752 priv->bcn_miss_rate = bcnMissRate;
2753 else
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302755
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302756 hdd_request_complete(request);
2757 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302758
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302759 return;
c_hpothu92367912014-05-01 15:18:17 +05302760}
2761
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302762struct fw_stats_priv {
2763 tSirFwStatsResult *fw_stats;
2764};
2765
2766/**
2767 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2768 * from firmware
2769 * @status: Status of get firmware stats operation
2770 * @fwStatsResult: firmware stats
2771 * @context: Context passed while registering callback
2772 *
2773 * This function is invoked by WDA layer on receiving
2774 * WDI_GET_FW_STATS_RSP
2775 *
2776 * Return: None
2777 */
2778static void hdd_fw_stats_cb(VOS_STATUS status,
2779 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302780{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302781 struct hdd_request *request;
2782 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302783
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302784 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302785
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302786 request = hdd_request_get(context);
2787 if (!request) {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2789 return;
2790 }
2791 priv = hdd_request_priv(request);
2792
2793 if (VOS_STATUS_SUCCESS == status)
2794 *priv->fw_stats = *fwStatsResult;
2795 else
2796 priv->fw_stats = NULL;
2797
2798 hdd_request_complete(request);
2799 hdd_request_put(request);
2800 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302801}
2802
jge35567202017-06-21 16:39:38 +08002803/*
2804 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2805 *@pValue Pointer to MAXTXPOWER command
2806 *@pTxPower Pointer to tx power
2807 *
2808 *This function parses the MAXTXPOWER command passed in the format
2809 * MAXTXPOWER<space>X(Tx power in dbm)
2810 * For example input commands:
2811 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2812 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2813 *
2814 *return - 0 for success non-zero for failure
2815 */
2816static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2817{
2818 unsigned char *inPtr = pValue;
2819 int tempInt;
2820 int v = 0;
2821 *pTxPower = 0;
2822
2823 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2824 /* no argument after the command */
2825 if (NULL == inPtr)
2826 return -EINVAL;
2827 /* no space after the command */
2828 else if (SPACE_ASCII_VALUE != *inPtr)
2829 return -EINVAL;
2830
2831 /* removing empty spaces */
2832 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2833
2834 /* no argument followed by spaces */
2835 if ('\0' == *inPtr)
2836 return 0;
2837
2838 v = kstrtos32(inPtr, 10, &tempInt);
2839
2840 /* Range checking for passed parameter */
2841 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2842 return -EINVAL;
2843
2844 *pTxPower = tempInt;
2845
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2847 "SETMAXTXPOWER: %d", *pTxPower);
2848
2849 return 0;
2850}
2851
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302852static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2853{
2854 int ret = 0;
2855
2856 if (!pCfg || !command || !extra || !len)
2857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2860 ret = -EINVAL;
2861 return ret;
2862 }
2863
2864 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2865 {
2866 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2867 (int)pCfg->nActiveMaxChnTime);
2868 return ret;
2869 }
2870 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2871 {
2872 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2873 (int)pCfg->nActiveMinChnTime);
2874 return ret;
2875 }
2876 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2877 {
2878 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2879 (int)pCfg->nPassiveMaxChnTime);
2880 return ret;
2881 }
2882 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2883 {
2884 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2885 (int)pCfg->nPassiveMinChnTime);
2886 return ret;
2887 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302888 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2889 {
2890 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2891 (int)pCfg->nActiveMaxChnTime);
2892 return ret;
2893 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302894 else
2895 {
2896 ret = -EINVAL;
2897 }
2898
2899 return ret;
2900}
2901
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302902/**
2903 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2904 * @pCfg: Pointer to HDD context
2905 * @command: ASCII text command that is received
2906 * @extra: Pointer to copy data sent to user
2907 * @n: size of 'extra' buffer
2908 * @len: length copied to 'extra' buffer
2909 *
2910 * Driver commands:
2911 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2912 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2913 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2914 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2915 *
2916 * Return: 0 for success non-zero for failure
2917 */
2918
2919static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2920 char *extra, tANI_U8 n, tANI_U8 *len)
2921{
2922 int ret = 0;
2923
2924 if (!pCfg || !command || !extra || !len)
2925 {
2926 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2927 ret = -EINVAL;
2928 return ret;
2929 }
2930
2931 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2932 {
2933 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2934 (int)pCfg->max_chntime_btc_esco);
2935 return ret;
2936 }
2937 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2938 {
2939 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2940 (int)pCfg->min_chntime_btc_esco);
2941 return ret;
2942 }
2943 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2944 {
2945 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2946 (int)pCfg->max_chntime_btc_sco);
2947 return ret;
2948 }
2949 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2950 {
2951 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2952 (int)pCfg->min_chntime_btc_sco);
2953 return ret;
2954 }
2955 else
2956 {
2957 ret = -EINVAL;
2958 }
2959
2960 return ret;
2961}
2962
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302963int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2964{
2965 if (command[len] != ' ')
2966 return -EINVAL;
2967
2968 return 0;
2969}
2970
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302971#ifdef WLAN_AP_STA_CONCURRENCY
2972
2973/**
2974 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2975 * @pCfg: Pointer to HDD context
2976 * @command: ASCII text command that is received
2977 * @extra: Pointer to copy data sent to user
2978 * @n: size of 'extra' buffer
2979 * @len: length copied to 'extra' buffer
2980 *
2981 * Driver commands:
2982 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2983 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2984 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2985 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2986 *
2987 * Return: 0 for success non-zero for failure
2988 */
2989
2990static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2991 char *extra, tANI_U8 n, tANI_U8 *len)
2992{
2993 int ret = 0;
2994
2995 if (!pCfg || !command || !extra || !len)
2996 {
2997 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2998 ret = -EINVAL;
2999 return ret;
3000 }
3001
3002 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
3003 {
3004 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3005 (int)pCfg->nActiveMaxChnTimeConc);
3006 return ret;
3007 }
3008 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3009 {
3010 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3011 (int)pCfg->nActiveMinChnTimeConc);
3012 return ret;
3013 }
3014 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3015 {
3016 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3017 (int)pCfg->nPassiveMaxChnTimeConc);
3018 return ret;
3019 }
3020 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3021 {
3022 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3023 (int)pCfg->nPassiveMinChnTimeConc);
3024 return ret;
3025 }
3026 else
3027 {
3028 ret = -EINVAL;
3029 }
3030
3031 return ret;
3032}
3033
3034/**
3035 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3036 * @pAdapter: Adapter upon which the command was received
3037 * @command: ASCII text command that is received
3038 *
3039 * Driver commands:
3040 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3041 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3042 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3043 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3044 *
3045 * Return: 0 for success non-zero for failure
3046 */
3047
3048static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3049{
3050 tHalHandle hHal;
3051 hdd_config_t *pCfg;
3052 tANI_U8 *value = command;
3053 int val = 0, ret = 0, temp = 0;
3054 tSmeConfigParams smeConfig;
3055
3056 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3057 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3058 {
3059 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3060 ret = -EINVAL;
3061 return ret;
3062 }
3063
3064 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3065 sme_GetConfigParam(hHal, &smeConfig);
3066
3067 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3068 {
3069 if (hdd_drv_cmd_validate(command, 27)) {
3070 hddLog(LOGE, FL("Invalid driver command"));
3071 return -EINVAL;
3072 }
3073
3074 value = value + 28;
3075 temp = kstrtou32(value, 10, &val);
3076 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3077 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3078 {
3079 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3080 ret = -EFAULT;
3081 return ret;
3082 }
3083 pCfg->nActiveMaxChnTimeConc = val;
3084 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3085 sme_UpdateConfig(hHal, &smeConfig);
3086 }
3087 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3088 {
3089 if (hdd_drv_cmd_validate(command, 27)) {
3090 hddLog(LOGE, FL("Invalid driver command"));
3091 return -EINVAL;
3092 }
3093
3094 value = value + 28;
3095 temp = kstrtou32(value, 10, &val);
3096 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3097 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3098 {
3099 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3100 ret = -EFAULT;
3101 return ret;
3102 }
3103 pCfg->nActiveMinChnTimeConc = val;
3104 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3105 sme_UpdateConfig(hHal, &smeConfig);
3106 }
3107 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3108 {
3109 if (hdd_drv_cmd_validate(command, 28)) {
3110 hddLog(LOGE, FL("Invalid driver command"));
3111 return -EINVAL;
3112 }
3113
3114 value = value + 29;
3115 temp = kstrtou32(value, 10, &val);
3116 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3117 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3118 {
3119 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3120 ret = -EFAULT;
3121 return ret;
3122 }
3123 pCfg->nPassiveMaxChnTimeConc = val;
3124 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3125 sme_UpdateConfig(hHal, &smeConfig);
3126 }
3127 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3128 {
3129 if (hdd_drv_cmd_validate(command, 28)) {
3130 hddLog(LOGE, FL("Invalid driver command"));
3131 return -EINVAL;
3132 }
3133
3134 value = value + 29;
3135 temp = kstrtou32(value, 10, &val);
3136 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3137 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3138 {
3139 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3140 ret = -EFAULT;
3141 return ret;
3142 }
3143 pCfg->nPassiveMinChnTimeConc = val;
3144 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3145 sme_UpdateConfig(hHal, &smeConfig);
3146 }
3147 else
3148 {
3149 ret = -EINVAL;
3150 }
3151
3152 return ret;
3153}
3154
3155#endif
3156
3157/**
3158 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3159 * @pAdapter: Adapter upon which the command was received
3160 * @command: ASCII text command that is received
3161 *
3162 * Driver commands:
3163 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3164 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3165 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3166 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3167 *
3168 * Return: 0 for success non-zero for failure
3169 */
3170
3171static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3172{
3173 tHalHandle hHal;
3174 hdd_config_t *pCfg;
3175 tANI_U8 *value = command;
3176 int val = 0, ret = 0, temp = 0;
3177 tSmeConfigParams smeConfig;
3178
3179 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3180 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3181 {
3182 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3183 ret = -EINVAL;
3184 return ret;
3185 }
3186
3187 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3188 sme_GetConfigParam(hHal, &smeConfig);
3189
3190 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3191 {
3192 if (hdd_drv_cmd_validate(command, 24)) {
3193 hddLog(LOGE, FL("Invalid driver command"));
3194 return -EINVAL;
3195 }
3196
3197 value = value + 25;
3198 temp = kstrtou32(value, 10, &val);
3199 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3200 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3201 {
3202 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3203 ret = -EFAULT;
3204 return ret;
3205 }
3206 pCfg->max_chntime_btc_esco = val;
3207 smeConfig.csrConfig.max_chntime_btc_esco = val;
3208 sme_UpdateConfig(hHal, &smeConfig);
3209 }
3210 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3211 {
3212 if (hdd_drv_cmd_validate(command, 24)) {
3213 hddLog(LOGE, FL("Invalid driver command"));
3214 return -EINVAL;
3215 }
3216
3217 value = value + 25;
3218 temp = kstrtou32(value, 10, &val);
3219 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3220 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3221 {
3222 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3223 ret = -EFAULT;
3224 return ret;
3225 }
3226 pCfg->min_chntime_btc_esco = val;
3227 smeConfig.csrConfig.min_chntime_btc_esco = val;
3228 sme_UpdateConfig(hHal, &smeConfig);
3229 }
3230 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3231 {
3232 if (hdd_drv_cmd_validate(command, 23)) {
3233 hddLog(LOGE, FL("Invalid driver command"));
3234 return -EINVAL;
3235 }
3236
3237 value = value + 24;
3238 temp = kstrtou32(value, 10, &val);
3239 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3240 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3241 {
3242 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3243 ret = -EFAULT;
3244 return ret;
3245 }
3246 pCfg->max_chntime_btc_sco = val;
3247 smeConfig.csrConfig.max_chntime_btc_sco = val;
3248 sme_UpdateConfig(hHal, &smeConfig);
3249 }
3250 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3251 {
3252 if (hdd_drv_cmd_validate(command, 23)) {
3253 hddLog(LOGE, FL("Invalid driver command"));
3254 return -EINVAL;
3255 }
3256
3257 value = value + 24;
3258 temp = kstrtou32(value, 10, &val);
3259 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3260 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3261 {
3262 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3263 ret = -EFAULT;
3264 return ret;
3265 }
3266 pCfg->min_chntime_btc_sco = val;
3267 smeConfig.csrConfig.min_chntime_btc_sco = val;
3268 sme_UpdateConfig(hHal, &smeConfig);
3269 }
3270 else
3271 {
3272 ret = -EINVAL;
3273 }
3274
3275 return ret;
3276}
3277
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303278static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3279{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303280 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303281 hdd_config_t *pCfg;
3282 tANI_U8 *value = command;
3283 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303284 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303285
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303286 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3287 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303288 {
3289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3290 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3291 ret = -EINVAL;
3292 return ret;
3293 }
3294
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303295 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3296 sme_GetConfigParam(hHal, &smeConfig);
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3299 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303300 if (hdd_drv_cmd_validate(command, 23))
3301 return -EINVAL;
3302
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303303 value = value + 24;
3304 temp = kstrtou32(value, 10, &val);
3305 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3306 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3307 {
3308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3309 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3310 ret = -EFAULT;
3311 return ret;
3312 }
3313 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303314 smeConfig.csrConfig.nActiveMaxChnTime = val;
3315 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303316 }
3317 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3318 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303319 if (hdd_drv_cmd_validate(command, 23))
3320 return -EINVAL;
3321
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303322 value = value + 24;
3323 temp = kstrtou32(value, 10, &val);
3324 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3325 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3326 {
3327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3328 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3329 ret = -EFAULT;
3330 return ret;
3331 }
3332 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303333 smeConfig.csrConfig.nActiveMinChnTime = val;
3334 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303335 }
3336 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3337 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303338 if (hdd_drv_cmd_validate(command, 24))
3339 return -EINVAL;
3340
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303341 value = value + 25;
3342 temp = kstrtou32(value, 10, &val);
3343 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3344 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3348 ret = -EFAULT;
3349 return ret;
3350 }
3351 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303352 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3353 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303354 }
3355 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3356 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303357 if (hdd_drv_cmd_validate(command, 24))
3358 return -EINVAL;
3359
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303360 value = value + 25;
3361 temp = kstrtou32(value, 10, &val);
3362 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3363 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3364 {
3365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3366 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3367 ret = -EFAULT;
3368 return ret;
3369 }
3370 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303371 smeConfig.csrConfig.nPassiveMinChnTime = val;
3372 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303373 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303374 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3375 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303376 if (hdd_drv_cmd_validate(command, 12))
3377 return -EINVAL;
3378
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303379 value = value + 13;
3380 temp = kstrtou32(value, 10, &val);
3381 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3382 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3383 {
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3386 ret = -EFAULT;
3387 return ret;
3388 }
3389 pCfg->nActiveMaxChnTime = val;
3390 smeConfig.csrConfig.nActiveMaxChnTime = val;
3391 sme_UpdateConfig(hHal, &smeConfig);
3392 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303393 else
3394 {
3395 ret = -EINVAL;
3396 }
3397
3398 return ret;
3399}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303400static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3401 tANI_U8 cmd_len)
3402{
3403 tANI_U8 *value;
3404 tANI_U8 fcc_constraint;
3405
3406 eHalStatus status;
3407 int ret = 0;
3408 value = cmd + cmd_len + 1;
3409
3410 ret = kstrtou8(value, 10, &fcc_constraint);
3411 if ((ret < 0) || (fcc_constraint > 1)) {
3412 /*
3413 * If the input value is greater than max value of datatype,
3414 * then also it is a failure
3415 */
3416 hddLog(VOS_TRACE_LEVEL_ERROR,
3417 "%s: value out of range", __func__);
3418 return -EINVAL;
3419 }
3420
Agrawal Ashish842eea82016-02-04 17:56:16 +05303421 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3422 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303423 if (status != eHAL_STATUS_SUCCESS)
3424 ret = -EPERM;
3425
3426 return ret;
3427}
3428
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303429/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303430
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303431 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3432 FW will send *ONE* CA ind to Host(even though it is duplicate).
3433 When Host send IOCTL (disable), FW doesn't perform any action.
3434 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3435 sends CA ind to host. (regard less of IOCTL status)
3436 \param - pHddCtx - HDD context
3437 \param - command - command received from framework
3438 \param - cmd_len - len of the command
3439
3440 \return - 0 on success, appropriate error values on failure.
3441
3442 --------------------------------------------------------------------------*/
3443int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3444{
3445 tANI_U8 set_value;
3446 int ret = 0;
3447 eHalStatus status;
3448
3449 ret = wlan_hdd_validate_context(pHddCtx);
3450 if (0 != ret)
3451 {
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455
3456 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3457 {
3458 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3459 " ini param to control channel avooidance indication");
3460 ret = 0;
3461 goto exit;
3462 }
3463
3464 set_value = command[cmd_len + 1] - '0';
3465 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3466 if (status != eHAL_STATUS_SUCCESS)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3469 " enableDisableChanAoidance command to SME\n", __func__);
3470 ret = -EINVAL;
3471 }
3472
3473exit:
3474 return ret;
3475}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303476
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303477/**
3478 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3479 * @pHddCtx: Pointer to the HDD context
3480 * @channel: channel to reassociate
3481 * @targetApBssid: Target AP/BSSID to reassociate
3482 *
3483 * Return: None
3484 */
3485#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3486static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3487 uint8_t channel, tSirMacAddr targetApBssid)
3488{
3489 tCsrHandoffRequest handoffInfo;
3490 handoffInfo.channel = channel;
3491 handoffInfo.src = FASTREASSOC;
3492 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3493 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3494}
3495#else
3496static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3497 uint8_t channel, tSirMacAddr targetApBssid)
3498{
3499}
3500#endif
3501
3502/**
3503 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3504 * @pAdapter: Pointer to HDD adapter
3505 * @channel: Channel to scan/roam
3506 * @targetApBssid: BSSID to roam
3507 *
3508 * Return: None
3509 */
3510#ifdef QCA_WIFI_ISOC
3511static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3512 uint8_t channel, tSirMacAddr targetApBssid)
3513{
3514 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3515 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3516}
3517#else
3518static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3519 uint8_t channel, tSirMacAddr targetApBssid)
3520{
3521}
3522#endif
3523
3524/**
3525 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3526 * @pAdapter: pointer to hdd adapter
3527 * @command: pointer to the command received
3528 *
3529 * Return: VOS_STATUS enum
3530 */
3531static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3532 uint8_t *command)
3533{
3534 tANI_U8 *value = command;
3535 tANI_U8 channel = 0;
3536 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303537 hdd_station_ctx_t *pHddStaCtx = NULL;
3538 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303539 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303540 tCsrRoamModifyProfileFields mod_profile_fields;
3541 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303542 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3544
3545 /* if not associated, no need to proceed with reassoc */
3546 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3547 hddLog(LOG1, FL("Not associated!"));
3548 return eHAL_STATUS_FAILURE;
3549 }
3550
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303551 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3552 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303553 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3554 return eHAL_STATUS_FAILURE;
3555 }
3556
3557 /* if the target bssid is same as currently associated AP,
3558 then no need to proceed with reassoc */
3559 if (vos_mem_compare(targetApBssid,
3560 pHddStaCtx->conn_info.bssId,
3561 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303562 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3563 &mod_profile_fields);
3564 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3565 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303566 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303567 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303568 }
3569
3570 /* Check channel number is a valid channel number */
3571 if (VOS_STATUS_SUCCESS !=
3572 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3573 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3574 return eHAL_STATUS_FAILURE;
3575 }
3576
3577 /* Proceed with reassoc */
3578 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3579
3580 /* Proceed with scan/roam */
3581 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3582
3583 return eHAL_STATUS_SUCCESS;
3584}
3585
3586/**
3587 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3588 * @handoffInfo: Pointer to the csr Handoff Request.
3589 *
3590 * Return: None
3591 */
3592#ifndef QCA_WIFI_ISOC
3593static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3594{
3595 handoffInfo->src = REASSOC;
3596}
3597#else
3598static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3599{
3600}
3601#endif
3602
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303603/**
3604 * wlan_hdd_free_cache_channels() - Free the cache channels list
3605 * @hdd_ctx: Pointer to HDD context
3606 *
3607 * Return: None
3608 */
3609
3610static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3611{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303612 if(!hdd_ctx || !hdd_ctx->original_channels)
3613 return;
3614
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303615 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303616 hdd_ctx->original_channels->num_channels = 0;
3617 vos_mem_free(hdd_ctx->original_channels->channel_info);
3618 hdd_ctx->original_channels->channel_info = NULL;
3619 vos_mem_free(hdd_ctx->original_channels);
3620 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303621 mutex_unlock(&hdd_ctx->cache_channel_lock);
3622}
3623
3624/**
3625 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3626 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3627 * @hdd_ctx: Pointer to HDD context
3628 * @num_chan: Number of channels for which memory needs to
3629 * be allocated
3630 *
3631 * Return: 0 on success and error code on failure
3632 */
3633
3634int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3635{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303636 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303637 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303638 if (!hdd_ctx->original_channels) {
3639 hddLog(VOS_TRACE_LEVEL_ERROR,
3640 "In %s, VOS_MALLOC_ERR", __func__);
3641 return -EINVAL;
3642 }
3643 hdd_ctx->original_channels->num_channels = num_chan;
3644 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303645 vos_mem_malloc(num_chan *
3646 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303647 if (!hdd_ctx->original_channels->channel_info) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR,
3649 "In %s, VOS_MALLOC_ERR", __func__);
3650 hdd_ctx->original_channels->num_channels = 0;
3651 vos_mem_free(hdd_ctx->original_channels);
3652 hdd_ctx->original_channels = NULL;
3653 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303654 }
3655 return 0;
3656
3657}
3658
3659
3660int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3661{
3662 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3663 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3664 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303665 int j, tempInt, ret = 0, i, num_channels;
3666 int parsed_channels[MAX_CHANNEL];
3667 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303668
3669 if (NULL == pvosGCtx) {
3670 hddLog(VOS_TRACE_LEVEL_FATAL,
3671 "VOS Global Context is NULL");
3672 return -EINVAL;
3673 }
3674
3675 if (NULL == hdd_ctx) {
3676 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3677 return -EINVAL;
3678 }
3679
3680 param = strchr(ptr, ' ');
3681 /*no argument after the command*/
3682 if (NULL == param)
3683 return -EINVAL;
3684
3685 /*no space after the command*/
3686 else if (SPACE_ASCII_VALUE != *param)
3687 return -EINVAL;
3688
3689 param++;
3690
3691 /*removing empty spaces*/
3692 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3693 param++;
3694
3695 /*no argument followed by spaces*/
3696 if ('\0' == *param)
3697 return -EINVAL;
3698
3699 /*getting the first argument ie the number of channels*/
3700 if (sscanf(param, "%d ", &tempInt) != 1) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR,
3702 "%s: Cannot get number of channels from input",
3703 __func__);
3704 return -EINVAL;
3705 }
3706
3707 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR,
3709 "%s: Invalid Number of channel received", __func__);
3710 return -EINVAL;
3711 }
3712
3713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3714 "%s: Number of channel to disable are: %d",
3715 __func__, tempInt);
3716
3717 if (!tempInt) {
3718 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3719 /*
3720 * Free the cache channels only when the command is
3721 * received with num channels as 0
3722 */
3723 wlan_hdd_free_cache_channels(hdd_ctx);
3724 }
3725 return 0;
3726 }
3727
3728 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303729 if (!hdd_ctx->original_channels) {
3730 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3731 ret = -ENOMEM;
3732 goto mem_alloc_failed;
3733 }
3734 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR,
3736 "%s, Invalid No of channel provided in the list",
3737 __func__);
3738 ret = -EINVAL;
3739 is_command_repeated = true;
3740 goto parse_failed;
3741 } else {
3742 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303743 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303744
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303745 num_channels = tempInt;
3746
3747 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303748 /*
3749 * param pointing to the beginning of first space
3750 * after number of channels
3751 */
3752 param = strpbrk(param, " ");
3753 /*no channel list after the number of channels argument*/
3754 if (NULL == param) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 "%s, Invalid No of channel provided in the list",
3757 __func__);
3758 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303759 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303760 }
3761
3762 param++;
3763
3764 /*removing empty space*/
3765 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3766 param++;
3767
3768 if ('\0' == *param) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR,
3770 "%s, No channel is provided in the list",
3771 __func__);
3772 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303773 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303774
3775 }
3776
3777 if (sscanf(param, "%d ", &tempInt) != 1) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR,
3779 "%s: Cannot read channel number",
3780 __func__);
3781 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303782 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303783
3784 }
3785
3786 if (!IS_CHANNEL_VALID(tempInt)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 "%s: Invalid channel number received",
3789 __func__);
3790 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303791 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303792
3793 }
3794
3795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3796 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303797
3798 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303799 }
3800
3801 /*extra arguments check*/
3802 param = strchr(param, ' ');
3803 if (NULL != param) {
3804 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3805 param++;
3806
3807 if ('\0' != *param) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 "%s: Invalid argument received", __func__);
3810 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303811 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303812 }
3813 }
3814
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303815 /*
3816 * If command is received first time, cache the channels to
3817 * be disabled else compare the channels received in the
3818 * command with the cached channels, if channel list matches
3819 * return success otherewise return failure.
3820 */
3821 if (!is_command_repeated)
3822 for (j = 0; j < num_channels; j++)
3823 hdd_ctx->original_channels->
3824 channel_info[j].channel_num =
3825 parsed_channels[j];
3826 else {
3827 for (i = 0; i < num_channels; i++) {
3828 for (j = 0; j < num_channels; j++)
3829 if (hdd_ctx->original_channels->
3830 channel_info[i].channel_num ==
3831 parsed_channels[j])
3832 break;
3833 if (j == num_channels) {
3834 ret = -EINVAL;
3835 goto parse_failed;
3836 }
3837 }
3838 ret = 0;
3839 }
3840
3841mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303842 mutex_unlock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +05303843 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
3844 if (!is_command_repeated) {
3845 wlan_hdd_disable_channels(hdd_ctx);
3846 hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
3847 }
3848
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303849 EXIT();
3850
3851 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303852
3853parse_failed:
3854 mutex_unlock(&hdd_ctx->cache_channel_lock);
3855 if (!is_command_repeated)
3856 wlan_hdd_free_cache_channels(hdd_ctx);
3857 EXIT();
3858 return ret;
3859
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303860}
3861
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303862int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303863 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303864{
3865 struct hdd_cache_channel_info *ch_list;
3866 unsigned char i, num_ch;
3867 int len = 0;
3868
3869 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303870 if (hdd_ctx->original_channels &&
3871 hdd_ctx->original_channels->num_channels &&
3872 hdd_ctx->original_channels->channel_info) {
3873 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303874
3875 len = scnprintf(buf, buf_len, "%s %hhu",
3876 "GET_DISABLE_CHANNEL_LIST", num_ch);
3877
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303878 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303879
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303880 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303881 len += scnprintf(buf + len, buf_len - len,
3882 " %d", ch_list[i].channel_num);
3883 }
3884 }
3885 mutex_unlock(&hdd_ctx->cache_channel_lock);
3886
3887 return len;
3888}
3889
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003890static int hdd_driver_command(hdd_adapter_t *pAdapter,
3891 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003892{
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 hdd_priv_data_t priv_data;
3894 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303895 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3896 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003897 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303898 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3900 struct cfg80211_mgmt_tx_params params;
3901#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303902
3903 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003904 /*
3905 * Note that valid pointers are provided by caller
3906 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003907
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003908 /* copy to local struct to avoid numerous changes to legacy code */
3909 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003910
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003911 if (priv_data.total_len <= 0 ||
3912 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003913 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003914 hddLog(VOS_TRACE_LEVEL_WARN,
3915 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3916 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003917 ret = -EINVAL;
3918 goto exit;
3919 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303920 status = wlan_hdd_validate_context(pHddCtx);
3921 if (0 != status)
3922 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303923 ret = -EINVAL;
3924 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303925 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003926 /* Allocate +1 for '\0' */
3927 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 if (!command)
3929 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003930 hddLog(VOS_TRACE_LEVEL_ERROR,
3931 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 ret = -ENOMEM;
3933 goto exit;
3934 }
3935
3936 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3937 {
3938 ret = -EFAULT;
3939 goto exit;
3940 }
3941
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003942 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003943 command[priv_data.total_len] = '\0';
3944
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003945 /* at one time the following block of code was conditional. braces
3946 * have been retained to avoid re-indenting the legacy code
3947 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003948 {
3949 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3950
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003952 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003953
3954 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3955 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3957 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3958 pAdapter->sessionId, (unsigned)
3959 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3960 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3961 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3962 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3964 sizeof(tSirMacAddr)))
3965 {
3966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003967 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 ret = -EFAULT;
3969 }
3970 }
Amar Singhal0974e402013-02-12 14:27:46 -08003971 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 {
Amar Singhal0974e402013-02-12 14:27:46 -08003973 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003974
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303975 ret = hdd_drv_cmd_validate(command, 7);
3976 if (ret)
3977 goto exit;
3978
Jeff Johnson295189b2012-06-20 16:38:30 -07003979 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003980
3981 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003982 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003984 "%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 +05303985 if(VOS_FTM_MODE != hdd_get_conparam())
3986 {
3987 /* Change band request received */
3988 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3989 if(ret < 0)
3990 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3991 "%s: failed to set band ret=%d", __func__, ret);
3992 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003993 }
Kiet Lamf040f472013-11-20 21:15:23 +05303994 else if(strncmp(command, "SETWMMPS", 8) == 0)
3995 {
3996 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303997
3998 ret = hdd_drv_cmd_validate(command, 8);
3999 if (ret)
4000 goto exit;
4001
Kiet Lamf040f472013-11-20 21:15:23 +05304002 ret = hdd_wmmps_helper(pAdapter, ptr);
4003 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05304004
4005 else if(strncmp(command, "TDLSSCAN", 8) == 0)
4006 {
4007 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304008
4009 ret = hdd_drv_cmd_validate(command, 8);
4010 if (ret)
4011 goto exit;
4012
Agarwal Ashishef54a182014-12-16 15:07:31 +05304013 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4014 }
4015
Jeff Johnson32d95a32012-09-10 13:15:23 -07004016 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4017 {
4018 char *country_code;
4019
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304020 ret = hdd_drv_cmd_validate(command, 7);
4021 if (ret)
4022 goto exit;
4023
Jeff Johnson32d95a32012-09-10 13:15:23 -07004024 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004025
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004026 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004027 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004028#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304029 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004030#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004031 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4032 (void *)(tSmeChangeCountryCallback)
4033 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304034 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004035 if (eHAL_STATUS_SUCCESS == ret)
4036 {
4037 ret = wait_for_completion_interruptible_timeout(
4038 &pAdapter->change_country_code,
4039 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4040 if (0 >= ret)
4041 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304043 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004044 }
4045 }
4046 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004047 {
4048 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004049 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004050 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004051 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004052
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004053 }
4054 /*
4055 command should be a string having format
4056 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4057 */
Amar Singhal0974e402013-02-12 14:27:46 -08004058 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004059 {
Amar Singhal0974e402013-02-12 14:27:46 -08004060 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004061
4062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004063 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004064
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004065 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004066 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304067
4068 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4069 {
4070 tANI_U8 *ptr;
4071
4072 ret = hdd_drv_cmd_validate(command, 10);
4073 if (ret)
4074 goto exit;
4075
4076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4077 "Received Command for VOWIFI mode in %s", __func__);
4078
4079 ptr = (tANI_U8*)command + 11;
4080 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4081 }
4082
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004083 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4084 {
4085 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304086 tANI_U8 *ptr;
4087
4088 ret = hdd_drv_cmd_validate(command, 14);
4089 if (ret)
4090 goto exit;
4091
4092 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004093
4094 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4096 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4097 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004098 hdd_set_wlan_suspend_mode(suspend);
4099 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004100#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4101 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4102 {
4103 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004104 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004105 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4106 eHalStatus status = eHAL_STATUS_SUCCESS;
4107
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304108 ret = hdd_drv_cmd_validate(command, 14);
4109 if (ret)
4110 goto exit;
4111
Srinivas Girigowdade697412013-02-14 16:31:48 -08004112 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4113 value = value + 15;
4114
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004115 /* Convert the value from ascii to integer */
4116 ret = kstrtos8(value, 10, &rssi);
4117 if (ret < 0)
4118 {
4119 /* If the input value is greater than max value of datatype, then also
4120 kstrtou8 fails */
4121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4122 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004123 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004124 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4125 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4126 ret = -EINVAL;
4127 goto exit;
4128 }
4129
Srinivas Girigowdade697412013-02-14 16:31:48 -08004130 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004131
Srinivas Girigowdade697412013-02-14 16:31:48 -08004132 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4133 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4134 {
4135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4136 "Neighbor lookup threshold value %d is out of range"
4137 " (Min: %d Max: %d)", lookUpThreshold,
4138 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4139 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4140 ret = -EINVAL;
4141 goto exit;
4142 }
4143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4145 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4146 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4148 "%s: Received Command to Set Roam trigger"
4149 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4150
4151 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4152 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4153 if (eHAL_STATUS_SUCCESS != status)
4154 {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4156 "%s: Failed to set roam trigger, try again", __func__);
4157 ret = -EPERM;
4158 goto exit;
4159 }
4160
4161 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304162 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004163 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4164 }
4165 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4166 {
4167 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4168 int rssi = (-1) * lookUpThreshold;
4169 char extra[32];
4170 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4172 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4173 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004174 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304175 len = VOS_MIN(priv_data.total_len, len + 1);
4176 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004177 {
4178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4179 "%s: failed to copy data to user buffer", __func__);
4180 ret = -EFAULT;
4181 goto exit;
4182 }
4183 }
4184 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4185 {
4186 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004187 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004188 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004189
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304190 ret = hdd_drv_cmd_validate(command, 17);
4191 if (ret)
4192 goto exit;
4193
Srinivas Girigowdade697412013-02-14 16:31:48 -08004194 /* input refresh period is in terms of seconds */
4195 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4196 value = value + 18;
4197 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004198 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004199 if (ret < 0)
4200 {
4201 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004202 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004204 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004205 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004206 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4207 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004208 ret = -EINVAL;
4209 goto exit;
4210 }
4211
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004212 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4213 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004214 {
4215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004216 "Roam scan period value %d is out of range"
4217 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004218 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4219 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004220 ret = -EINVAL;
4221 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304222 }
4223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4224 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4225 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004226 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004227
4228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4229 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004230 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004231
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004232 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4233 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004234 }
4235 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4236 {
4237 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4238 char extra[32];
4239 tANI_U8 len = 0;
4240
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304241 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4242 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4243 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004244 len = scnprintf(extra, sizeof(extra), "%s %d",
4245 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004246 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304247 len = VOS_MIN(priv_data.total_len, len + 1);
4248 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4250 "%s: failed to copy data to user buffer", __func__);
4251 ret = -EFAULT;
4252 goto exit;
4253 }
4254 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004255 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4256 {
4257 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004258 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004259 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004260
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304261 ret = hdd_drv_cmd_validate(command, 24);
4262 if (ret)
4263 goto exit;
4264
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004265 /* input refresh period is in terms of seconds */
4266 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4267 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004268
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004269 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004270 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004271 if (ret < 0)
4272 {
4273 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004274 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004276 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004277 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004278 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4279 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4280 ret = -EINVAL;
4281 goto exit;
4282 }
4283
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004284 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4285 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4286 {
4287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4288 "Neighbor scan results refresh period value %d is out of range"
4289 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4290 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4291 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4292 ret = -EINVAL;
4293 goto exit;
4294 }
4295 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4296
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4298 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004299 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004300
4301 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4302 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4303 }
4304 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4305 {
4306 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4307 char extra[32];
4308 tANI_U8 len = 0;
4309
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004310 len = scnprintf(extra, sizeof(extra), "%s %d",
4311 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004312 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304313 len = VOS_MIN(priv_data.total_len, len + 1);
4314 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4316 "%s: failed to copy data to user buffer", __func__);
4317 ret = -EFAULT;
4318 goto exit;
4319 }
4320 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004321#ifdef FEATURE_WLAN_LFR
4322 /* SETROAMMODE */
4323 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4324 {
4325 tANI_U8 *value = command;
4326 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4327
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304328 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4329 hddLog(LOGE,
4330 FL("Roaming is always disabled in STA + MON concurrency"));
4331 ret = -EINVAL;
4332 goto exit;
4333 }
4334
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304335 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4336 if (ret)
4337 goto exit;
4338
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004339 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4340 value = value + SIZE_OF_SETROAMMODE + 1;
4341
4342 /* Convert the value from ascii to integer */
4343 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4344 if (ret < 0)
4345 {
4346 /* If the input value is greater than max value of datatype, then also
4347 kstrtou8 fails */
4348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4349 "%s: kstrtou8 failed range [%d - %d]", __func__,
4350 CFG_LFR_FEATURE_ENABLED_MIN,
4351 CFG_LFR_FEATURE_ENABLED_MAX);
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4356 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4357 {
4358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4359 "Roam Mode value %d is out of range"
4360 " (Min: %d Max: %d)", roamMode,
4361 CFG_LFR_FEATURE_ENABLED_MIN,
4362 CFG_LFR_FEATURE_ENABLED_MAX);
4363 ret = -EINVAL;
4364 goto exit;
4365 }
4366
4367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4368 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4369 /*
4370 * Note that
4371 * SETROAMMODE 0 is to enable LFR while
4372 * SETROAMMODE 1 is to disable LFR, but
4373 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4374 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4375 */
4376 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4377 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4378 else
4379 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4380
4381 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4382 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4383 }
4384 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304385 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004386 {
4387 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4388 char extra[32];
4389 tANI_U8 len = 0;
4390
4391 /*
4392 * roamMode value shall be inverted because the sementics is different.
4393 */
4394 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4395 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4396 else
4397 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4398
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004399 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304400 len = VOS_MIN(priv_data.total_len, len + 1);
4401 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4403 "%s: failed to copy data to user buffer", __func__);
4404 ret = -EFAULT;
4405 goto exit;
4406 }
4407 }
4408#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004409#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004410#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004411 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4412 {
4413 tANI_U8 *value = command;
4414 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4415
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304416 ret = hdd_drv_cmd_validate(command, 12);
4417 if (ret)
4418 goto exit;
4419
Srinivas Girigowdade697412013-02-14 16:31:48 -08004420 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4421 value = value + 13;
4422 /* Convert the value from ascii to integer */
4423 ret = kstrtou8(value, 10, &roamRssiDiff);
4424 if (ret < 0)
4425 {
4426 /* If the input value is greater than max value of datatype, then also
4427 kstrtou8 fails */
4428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4429 "%s: kstrtou8 failed range [%d - %d]", __func__,
4430 CFG_ROAM_RSSI_DIFF_MIN,
4431 CFG_ROAM_RSSI_DIFF_MAX);
4432 ret = -EINVAL;
4433 goto exit;
4434 }
4435
4436 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4437 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4438 {
4439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4440 "Roam rssi diff value %d is out of range"
4441 " (Min: %d Max: %d)", roamRssiDiff,
4442 CFG_ROAM_RSSI_DIFF_MIN,
4443 CFG_ROAM_RSSI_DIFF_MAX);
4444 ret = -EINVAL;
4445 goto exit;
4446 }
4447
4448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4449 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4450
4451 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4452 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4453 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304454 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004455 {
4456 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4457 char extra[32];
4458 tANI_U8 len = 0;
4459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4461 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4462 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004463 len = scnprintf(extra, sizeof(extra), "%s %d",
4464 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304465 len = VOS_MIN(priv_data.total_len, len + 1);
4466 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4468 "%s: failed to copy data to user buffer", __func__);
4469 ret = -EFAULT;
4470 goto exit;
4471 }
4472 }
4473#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004474#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004475 else if (strncmp(command, "GETBAND", 7) == 0)
4476 {
4477 int band = -1;
4478 char extra[32];
4479 tANI_U8 len = 0;
4480 hdd_getBand_helper(pHddCtx, &band);
4481
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4483 TRACE_CODE_HDD_GETBAND_IOCTL,
4484 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004485 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304486 len = VOS_MIN(priv_data.total_len, len + 1);
4487 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4489 "%s: failed to copy data to user buffer", __func__);
4490 ret = -EFAULT;
4491 goto exit;
4492 }
4493 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004494 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4495 {
4496 tANI_U8 *value = command;
4497 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4498 tANI_U8 numChannels = 0;
4499 eHalStatus status = eHAL_STATUS_SUCCESS;
4500
4501 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4502 if (eHAL_STATUS_SUCCESS != status)
4503 {
4504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4505 "%s: Failed to parse channel list information", __func__);
4506 ret = -EINVAL;
4507 goto exit;
4508 }
4509
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304510 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4511 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4512 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004513 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4514 {
4515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4516 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4517 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4518 ret = -EINVAL;
4519 goto exit;
4520 }
4521 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4522 numChannels);
4523 if (eHAL_STATUS_SUCCESS != status)
4524 {
4525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4526 "%s: Failed to update channel list information", __func__);
4527 ret = -EINVAL;
4528 goto exit;
4529 }
4530 }
4531 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4532 {
4533 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4534 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004535 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004536 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004537 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004538
4539 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4540 ChannelList, &numChannels ))
4541 {
4542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4543 "%s: failed to get roam scan channel list", __func__);
4544 ret = -EFAULT;
4545 goto exit;
4546 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304547 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4548 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4549 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004550 /* output channel list is of the format
4551 [Number of roam scan channels][Channel1][Channel2]... */
4552 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004553 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304554 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004555 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004556 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4557 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004558 }
4559
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304560 len = VOS_MIN(priv_data.total_len, len + 1);
4561 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004562 {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4564 "%s: failed to copy data to user buffer", __func__);
4565 ret = -EFAULT;
4566 goto exit;
4567 }
4568 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004569 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4570 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004571 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004572 char extra[32];
4573 tANI_U8 len = 0;
4574
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004575 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004576 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004577 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004578 hdd_is_okc_mode_enabled(pHddCtx) &&
4579 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4580 {
4581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004582 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004583 " hence this operation is not permitted!", __func__);
4584 ret = -EPERM;
4585 goto exit;
4586 }
4587
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004588 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304590 len = VOS_MIN(priv_data.total_len, len + 1);
4591 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004592 {
4593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4594 "%s: failed to copy data to user buffer", __func__);
4595 ret = -EFAULT;
4596 goto exit;
4597 }
4598 }
4599 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4600 {
4601 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4602 char extra[32];
4603 tANI_U8 len = 0;
4604
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004605 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004606 then this operation is not permitted (return FAILURE) */
4607 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004608 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004609 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4610 {
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004612 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004613 " hence this operation is not permitted!", __func__);
4614 ret = -EPERM;
4615 goto exit;
4616 }
4617
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004618 len = scnprintf(extra, sizeof(extra), "%s %d",
4619 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304620 len = VOS_MIN(priv_data.total_len, len + 1);
4621 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004622 {
4623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4624 "%s: failed to copy data to user buffer", __func__);
4625 ret = -EFAULT;
4626 goto exit;
4627 }
4628 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004629 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004630 {
4631 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4632 char extra[32];
4633 tANI_U8 len = 0;
4634
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004635 len = scnprintf(extra, sizeof(extra), "%s %d",
4636 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304637 len = VOS_MIN(priv_data.total_len, len + 1);
4638 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004639 {
4640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4641 "%s: failed to copy data to user buffer", __func__);
4642 ret = -EFAULT;
4643 goto exit;
4644 }
4645 }
4646 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4647 {
4648 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4649 char extra[32];
4650 tANI_U8 len = 0;
4651
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004652 len = scnprintf(extra, sizeof(extra), "%s %d",
4653 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304654 len = VOS_MIN(priv_data.total_len, len + 1);
4655 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004656 {
4657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4658 "%s: failed to copy data to user buffer", __func__);
4659 ret = -EFAULT;
4660 goto exit;
4661 }
4662 }
4663 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4664 {
4665 tANI_U8 *value = command;
4666 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4667
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304668 ret = hdd_drv_cmd_validate(command, 25);
4669 if (ret)
4670 goto exit;
4671
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004672 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4673 value = value + 26;
4674 /* Convert the value from ascii to integer */
4675 ret = kstrtou8(value, 10, &minTime);
4676 if (ret < 0)
4677 {
4678 /* If the input value is greater than max value of datatype, then also
4679 kstrtou8 fails */
4680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4681 "%s: kstrtou8 failed range [%d - %d]", __func__,
4682 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4683 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4684 ret = -EINVAL;
4685 goto exit;
4686 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004687 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4688 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4689 {
4690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4691 "scan min channel time value %d is out of range"
4692 " (Min: %d Max: %d)", minTime,
4693 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4694 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4695 ret = -EINVAL;
4696 goto exit;
4697 }
4698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4700 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4701 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4703 "%s: Received Command to change channel min time = %d", __func__, minTime);
4704
4705 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4706 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4707 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004708 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4709 {
4710 tANI_U8 *value = command;
4711 tANI_U8 channel = 0;
4712 tANI_U8 dwellTime = 0;
4713 tANI_U8 bufLen = 0;
4714 tANI_U8 *buf = NULL;
4715 tSirMacAddr targetApBssid;
4716 eHalStatus status = eHAL_STATUS_SUCCESS;
4717 struct ieee80211_channel chan;
4718 tANI_U8 finalLen = 0;
4719 tANI_U8 *finalBuf = NULL;
4720 tANI_U8 temp = 0;
4721 u64 cookie;
4722 hdd_station_ctx_t *pHddStaCtx = NULL;
4723 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4724
4725 /* if not associated, no need to send action frame */
4726 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4727 {
4728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4729 ret = -EINVAL;
4730 goto exit;
4731 }
4732
4733 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4734 &dwellTime, &buf, &bufLen);
4735 if (eHAL_STATUS_SUCCESS != status)
4736 {
4737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4738 "%s: Failed to parse send action frame data", __func__);
4739 ret = -EINVAL;
4740 goto exit;
4741 }
4742
4743 /* if the target bssid is different from currently associated AP,
4744 then no need to send action frame */
4745 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4746 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4747 {
4748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4749 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004750 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004751 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004752 goto exit;
4753 }
4754
4755 /* if the channel number is different from operating channel then
4756 no need to send action frame */
4757 if (channel != pHddStaCtx->conn_info.operationChannel)
4758 {
4759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4760 "%s: channel(%d) is different from operating channel(%d)",
4761 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4762 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004763 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004764 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004765 goto exit;
4766 }
4767 chan.center_freq = sme_ChnToFreq(channel);
4768
4769 finalLen = bufLen + 24;
4770 finalBuf = vos_mem_malloc(finalLen);
4771 if (NULL == finalBuf)
4772 {
4773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4774 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004775 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004776 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004777 goto exit;
4778 }
4779 vos_mem_zero(finalBuf, finalLen);
4780
4781 /* Fill subtype */
4782 temp = SIR_MAC_MGMT_ACTION << 4;
4783 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4784
4785 /* Fill type */
4786 temp = SIR_MAC_MGMT_FRAME;
4787 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4788
4789 /* Fill destination address (bssid of the AP) */
4790 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4791
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004792 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004793 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4794
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004795 /* Fill BSSID (AP mac address) */
4796 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004797
4798 /* Fill received buffer from 24th address */
4799 vos_mem_copy(finalBuf + 24, buf, bufLen);
4800
Jeff Johnson11c33152013-04-16 17:52:40 -07004801 /* done with the parsed buffer */
4802 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004803 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004804
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4806 params.chan = &chan;
4807 params.offchan = 0;
4808 params.wait = dwellTime;
4809 params.buf = finalBuf;
4810 params.len = finalLen;
4811 params.no_cck = 1;
4812 params.dont_wait_for_ack = 1;
4813 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4814#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304815 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004816#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4817 &(pAdapter->wdev),
4818#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004819 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004820#endif
4821 &chan, 0,
4822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4823 NL80211_CHAN_HT20, 1,
4824#endif
4825 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004826 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304827#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004828 vos_mem_free(finalBuf);
4829 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004830 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4831 {
4832 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4833 char extra[32];
4834 tANI_U8 len = 0;
4835
4836 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004837 len = scnprintf(extra, sizeof(extra), "%s %d",
4838 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4840 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4841 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304842 len = VOS_MIN(priv_data.total_len, len + 1);
4843 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004844 {
4845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4846 "%s: failed to copy data to user buffer", __func__);
4847 ret = -EFAULT;
4848 goto exit;
4849 }
4850 }
4851 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4852 {
4853 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004854 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004855
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304856 ret = hdd_drv_cmd_validate(command, 18);
4857 if (ret)
4858 goto exit;
4859
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004860 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4861 value = value + 19;
4862 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004863 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004864 if (ret < 0)
4865 {
4866 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004867 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004869 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004870 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4871 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4872 ret = -EINVAL;
4873 goto exit;
4874 }
4875
4876 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4877 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4878 {
4879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4880 "lfr mode value %d is out of range"
4881 " (Min: %d Max: %d)", maxTime,
4882 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4883 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4884 ret = -EINVAL;
4885 goto exit;
4886 }
4887
4888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4889 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4890
4891 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4892 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4893 }
4894 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4895 {
4896 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4897 char extra[32];
4898 tANI_U8 len = 0;
4899
4900 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004901 len = scnprintf(extra, sizeof(extra), "%s %d",
4902 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304903 len = VOS_MIN(priv_data.total_len, len + 1);
4904 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004905 {
4906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4907 "%s: failed to copy data to user buffer", __func__);
4908 ret = -EFAULT;
4909 goto exit;
4910 }
4911 }
4912 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4913 {
4914 tANI_U8 *value = command;
4915 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4916
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304917 ret = hdd_drv_cmd_validate(command, 15);
4918 if (ret)
4919 goto exit;
4920
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004921 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4922 value = value + 16;
4923 /* Convert the value from ascii to integer */
4924 ret = kstrtou16(value, 10, &val);
4925 if (ret < 0)
4926 {
4927 /* If the input value is greater than max value of datatype, then also
4928 kstrtou16 fails */
4929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4930 "%s: kstrtou16 failed range [%d - %d]", __func__,
4931 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4932 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4933 ret = -EINVAL;
4934 goto exit;
4935 }
4936
4937 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4938 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4939 {
4940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4941 "scan home time value %d is out of range"
4942 " (Min: %d Max: %d)", val,
4943 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4944 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4945 ret = -EINVAL;
4946 goto exit;
4947 }
4948
4949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4950 "%s: Received Command to change scan home time = %d", __func__, val);
4951
4952 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4953 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4954 }
4955 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4956 {
4957 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4958 char extra[32];
4959 tANI_U8 len = 0;
4960
4961 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004962 len = scnprintf(extra, sizeof(extra), "%s %d",
4963 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304964 len = VOS_MIN(priv_data.total_len, len + 1);
4965 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004966 {
4967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4968 "%s: failed to copy data to user buffer", __func__);
4969 ret = -EFAULT;
4970 goto exit;
4971 }
4972 }
4973 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4974 {
4975 tANI_U8 *value = command;
4976 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4977
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304978 ret = hdd_drv_cmd_validate(command, 16);
4979 if (ret)
4980 goto exit;
4981
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004982 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4983 value = value + 17;
4984 /* Convert the value from ascii to integer */
4985 ret = kstrtou8(value, 10, &val);
4986 if (ret < 0)
4987 {
4988 /* If the input value is greater than max value of datatype, then also
4989 kstrtou8 fails */
4990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4991 "%s: kstrtou8 failed range [%d - %d]", __func__,
4992 CFG_ROAM_INTRA_BAND_MIN,
4993 CFG_ROAM_INTRA_BAND_MAX);
4994 ret = -EINVAL;
4995 goto exit;
4996 }
4997
4998 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4999 (val > CFG_ROAM_INTRA_BAND_MAX))
5000 {
5001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5002 "intra band mode value %d is out of range"
5003 " (Min: %d Max: %d)", val,
5004 CFG_ROAM_INTRA_BAND_MIN,
5005 CFG_ROAM_INTRA_BAND_MAX);
5006 ret = -EINVAL;
5007 goto exit;
5008 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5010 "%s: Received Command to change intra band = %d", __func__, val);
5011
5012 pHddCtx->cfg_ini->nRoamIntraBand = val;
5013 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5014 }
5015 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5016 {
5017 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5018 char extra[32];
5019 tANI_U8 len = 0;
5020
5021 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005022 len = scnprintf(extra, sizeof(extra), "%s %d",
5023 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305024 len = VOS_MIN(priv_data.total_len, len + 1);
5025 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005026 {
5027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5028 "%s: failed to copy data to user buffer", __func__);
5029 ret = -EFAULT;
5030 goto exit;
5031 }
5032 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005033 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5034 {
5035 tANI_U8 *value = command;
5036 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5037
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305038 ret = hdd_drv_cmd_validate(command, 14);
5039 if (ret)
5040 goto exit;
5041
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005042 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5043 value = value + 15;
5044 /* Convert the value from ascii to integer */
5045 ret = kstrtou8(value, 10, &nProbes);
5046 if (ret < 0)
5047 {
5048 /* If the input value is greater than max value of datatype, then also
5049 kstrtou8 fails */
5050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5051 "%s: kstrtou8 failed range [%d - %d]", __func__,
5052 CFG_ROAM_SCAN_N_PROBES_MIN,
5053 CFG_ROAM_SCAN_N_PROBES_MAX);
5054 ret = -EINVAL;
5055 goto exit;
5056 }
5057
5058 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5059 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5060 {
5061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5062 "NProbes value %d is out of range"
5063 " (Min: %d Max: %d)", nProbes,
5064 CFG_ROAM_SCAN_N_PROBES_MIN,
5065 CFG_ROAM_SCAN_N_PROBES_MAX);
5066 ret = -EINVAL;
5067 goto exit;
5068 }
5069
5070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5071 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5072
5073 pHddCtx->cfg_ini->nProbes = nProbes;
5074 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5075 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305076 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005077 {
5078 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5079 char extra[32];
5080 tANI_U8 len = 0;
5081
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005082 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305083 len = VOS_MIN(priv_data.total_len, len + 1);
5084 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5086 "%s: failed to copy data to user buffer", __func__);
5087 ret = -EFAULT;
5088 goto exit;
5089 }
5090 }
5091 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5092 {
5093 tANI_U8 *value = command;
5094 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5095
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305096 ret = hdd_drv_cmd_validate(command, 19);
5097 if (ret)
5098 goto exit;
5099
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005100 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5101 /* input value is in units of msec */
5102 value = value + 20;
5103 /* Convert the value from ascii to integer */
5104 ret = kstrtou16(value, 10, &homeAwayTime);
5105 if (ret < 0)
5106 {
5107 /* If the input value is greater than max value of datatype, then also
5108 kstrtou8 fails */
5109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5110 "%s: kstrtou8 failed range [%d - %d]", __func__,
5111 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5112 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5113 ret = -EINVAL;
5114 goto exit;
5115 }
5116
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005117 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5118 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5119 {
5120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5121 "homeAwayTime value %d is out of range"
5122 " (Min: %d Max: %d)", homeAwayTime,
5123 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5124 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5125 ret = -EINVAL;
5126 goto exit;
5127 }
5128
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5130 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005131 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5132 {
5133 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5134 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5135 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005136 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305137 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005138 {
5139 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5140 char extra[32];
5141 tANI_U8 len = 0;
5142
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005143 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305144 len = VOS_MIN(priv_data.total_len, len + 1);
5145 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5147 "%s: failed to copy data to user buffer", __func__);
5148 ret = -EFAULT;
5149 goto exit;
5150 }
5151 }
5152 else if (strncmp(command, "REASSOC", 7) == 0)
5153 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305154 ret = hdd_drv_cmd_validate(command, 7);
5155 if (ret)
5156 goto exit;
5157
5158 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305159 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005160 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005161 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005162 else if (strncmp(command, "SETWESMODE", 10) == 0)
5163 {
5164 tANI_U8 *value = command;
5165 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5166
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305167 ret = hdd_drv_cmd_validate(command, 10);
5168 if (ret)
5169 goto exit;
5170
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005171 /* Move pointer to ahead of SETWESMODE<delimiter> */
5172 value = value + 11;
5173 /* Convert the value from ascii to integer */
5174 ret = kstrtou8(value, 10, &wesMode);
5175 if (ret < 0)
5176 {
5177 /* If the input value is greater than max value of datatype, then also
5178 kstrtou8 fails */
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5180 "%s: kstrtou8 failed range [%d - %d]", __func__,
5181 CFG_ENABLE_WES_MODE_NAME_MIN,
5182 CFG_ENABLE_WES_MODE_NAME_MAX);
5183 ret = -EINVAL;
5184 goto exit;
5185 }
5186
5187 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5188 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5189 {
5190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5191 "WES Mode value %d is out of range"
5192 " (Min: %d Max: %d)", wesMode,
5193 CFG_ENABLE_WES_MODE_NAME_MIN,
5194 CFG_ENABLE_WES_MODE_NAME_MAX);
5195 ret = -EINVAL;
5196 goto exit;
5197 }
5198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5199 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5200
5201 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5202 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5203 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305204 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005205 {
5206 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5207 char extra[32];
5208 tANI_U8 len = 0;
5209
Arif Hussain826d9412013-11-12 16:44:54 -08005210 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305211 len = VOS_MIN(priv_data.total_len, len + 1);
5212 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5214 "%s: failed to copy data to user buffer", __func__);
5215 ret = -EFAULT;
5216 goto exit;
5217 }
5218 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005219#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005220#ifdef FEATURE_WLAN_LFR
5221 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5222 {
5223 tANI_U8 *value = command;
5224 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5225
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305226 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5227 hddLog(LOGE,
5228 FL("Roaming is always disabled in STA + MON concurrency"));
5229 ret = -EINVAL;
5230 goto exit;
5231 }
5232
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305233 ret = hdd_drv_cmd_validate(command, 11);
5234 if (ret)
5235 goto exit;
5236
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005237 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5238 value = value + 12;
5239 /* Convert the value from ascii to integer */
5240 ret = kstrtou8(value, 10, &lfrMode);
5241 if (ret < 0)
5242 {
5243 /* If the input value is greater than max value of datatype, then also
5244 kstrtou8 fails */
5245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5246 "%s: kstrtou8 failed range [%d - %d]", __func__,
5247 CFG_LFR_FEATURE_ENABLED_MIN,
5248 CFG_LFR_FEATURE_ENABLED_MAX);
5249 ret = -EINVAL;
5250 goto exit;
5251 }
5252
5253 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5254 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5255 {
5256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5257 "lfr mode value %d is out of range"
5258 " (Min: %d Max: %d)", lfrMode,
5259 CFG_LFR_FEATURE_ENABLED_MIN,
5260 CFG_LFR_FEATURE_ENABLED_MAX);
5261 ret = -EINVAL;
5262 goto exit;
5263 }
5264
5265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5266 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5267
5268 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5269 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5270 }
5271#endif
5272#ifdef WLAN_FEATURE_VOWIFI_11R
5273 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5274 {
5275 tANI_U8 *value = command;
5276 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5277
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305278 ret = hdd_drv_cmd_validate(command, 17);
5279 if (ret)
5280 goto exit;
5281
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005282 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5283 value = value + 18;
5284 /* Convert the value from ascii to integer */
5285 ret = kstrtou8(value, 10, &ft);
5286 if (ret < 0)
5287 {
5288 /* If the input value is greater than max value of datatype, then also
5289 kstrtou8 fails */
5290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5291 "%s: kstrtou8 failed range [%d - %d]", __func__,
5292 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5293 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5294 ret = -EINVAL;
5295 goto exit;
5296 }
5297
5298 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5299 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5300 {
5301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5302 "ft mode value %d is out of range"
5303 " (Min: %d Max: %d)", ft,
5304 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5305 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5306 ret = -EINVAL;
5307 goto exit;
5308 }
5309
5310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5311 "%s: Received Command to change ft mode = %d", __func__, ft);
5312
5313 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5314 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5315 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305316 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5317 {
5318 tANI_U8 *value = command;
5319 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305320
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305321 ret = hdd_drv_cmd_validate(command, 14);
5322 if (ret)
5323 goto exit;
5324
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305325 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5326 value = value + 15;
5327 /* Convert the value from ascii to integer */
5328 ret = kstrtou8(value, 10, &dfsScanMode);
5329 if (ret < 0)
5330 {
5331 /* If the input value is greater than max value of
5332 datatype, then also kstrtou8 fails
5333 */
5334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5335 "%s: kstrtou8 failed range [%d - %d]", __func__,
5336 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5337 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5338 ret = -EINVAL;
5339 goto exit;
5340 }
5341
5342 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5343 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5344 {
5345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5346 "dfsScanMode value %d is out of range"
5347 " (Min: %d Max: %d)", dfsScanMode,
5348 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5349 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5350 ret = -EINVAL;
5351 goto exit;
5352 }
5353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5354 "%s: Received Command to Set DFS Scan Mode = %d",
5355 __func__, dfsScanMode);
5356
5357 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5358 }
5359 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5360 {
5361 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5362 char extra[32];
5363 tANI_U8 len = 0;
5364
5365 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305366 len = VOS_MIN(priv_data.total_len, len + 1);
5367 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305368 {
5369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5370 "%s: failed to copy data to user buffer", __func__);
5371 ret = -EFAULT;
5372 goto exit;
5373 }
5374 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305375 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5376 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305377 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5378 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305379 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305380 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005381#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005382#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005383 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5384 {
5385 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005386 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005387
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305388 ret = hdd_drv_cmd_validate(command, 10);
5389 if (ret)
5390 goto exit;
5391
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005392 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005393 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005394 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005395 hdd_is_okc_mode_enabled(pHddCtx) &&
5396 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5397 {
5398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005399 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005400 " hence this operation is not permitted!", __func__);
5401 ret = -EPERM;
5402 goto exit;
5403 }
5404
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005405 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5406 value = value + 11;
5407 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005408 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005409 if (ret < 0)
5410 {
5411 /* If the input value is greater than max value of datatype, then also
5412 kstrtou8 fails */
5413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5414 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005415 CFG_ESE_FEATURE_ENABLED_MIN,
5416 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005417 ret = -EINVAL;
5418 goto exit;
5419 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005420 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5421 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005422 {
5423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005424 "Ese mode value %d is out of range"
5425 " (Min: %d Max: %d)", eseMode,
5426 CFG_ESE_FEATURE_ENABLED_MIN,
5427 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005428 ret = -EINVAL;
5429 goto exit;
5430 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005432 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005433
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005434 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5435 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005436 }
5437#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005438 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5439 {
5440 tANI_U8 *value = command;
5441 tANI_BOOLEAN roamScanControl = 0;
5442
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305443 ret = hdd_drv_cmd_validate(command, 18);
5444 if (ret)
5445 goto exit;
5446
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005447 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5448 value = value + 19;
5449 /* Convert the value from ascii to integer */
5450 ret = kstrtou8(value, 10, &roamScanControl);
5451 if (ret < 0)
5452 {
5453 /* If the input value is greater than max value of datatype, then also
5454 kstrtou8 fails */
5455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5456 "%s: kstrtou8 failed ", __func__);
5457 ret = -EINVAL;
5458 goto exit;
5459 }
5460
5461 if (0 != roamScanControl)
5462 {
5463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5464 "roam scan control invalid value = %d",
5465 roamScanControl);
5466 ret = -EINVAL;
5467 goto exit;
5468 }
5469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5470 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5471
5472 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5473 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005474#ifdef FEATURE_WLAN_OKC
5475 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5476 {
5477 tANI_U8 *value = command;
5478 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5479
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305480 ret = hdd_drv_cmd_validate(command, 10);
5481 if (ret)
5482 goto exit;
5483
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005484 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005485 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005486 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005487 hdd_is_okc_mode_enabled(pHddCtx) &&
5488 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5489 {
5490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005491 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005492 " hence this operation is not permitted!", __func__);
5493 ret = -EPERM;
5494 goto exit;
5495 }
5496
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005497 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5498 value = value + 11;
5499 /* Convert the value from ascii to integer */
5500 ret = kstrtou8(value, 10, &okcMode);
5501 if (ret < 0)
5502 {
5503 /* If the input value is greater than max value of datatype, then also
5504 kstrtou8 fails */
5505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5506 "%s: kstrtou8 failed range [%d - %d]", __func__,
5507 CFG_OKC_FEATURE_ENABLED_MIN,
5508 CFG_OKC_FEATURE_ENABLED_MAX);
5509 ret = -EINVAL;
5510 goto exit;
5511 }
5512
5513 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5514 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5515 {
5516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5517 "Okc mode value %d is out of range"
5518 " (Min: %d Max: %d)", okcMode,
5519 CFG_OKC_FEATURE_ENABLED_MIN,
5520 CFG_OKC_FEATURE_ENABLED_MAX);
5521 ret = -EINVAL;
5522 goto exit;
5523 }
5524
5525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5526 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5527
5528 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5529 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005530#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305531 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005532 {
5533 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5534 char extra[32];
5535 tANI_U8 len = 0;
5536
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005537 len = scnprintf(extra, sizeof(extra), "%s %d",
5538 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305539 len = VOS_MIN(priv_data.total_len, len + 1);
5540 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5542 "%s: failed to copy data to user buffer", __func__);
5543 ret = -EFAULT;
5544 goto exit;
5545 }
5546 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305547#ifdef WLAN_FEATURE_PACKET_FILTERING
5548 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5549 {
5550 tANI_U8 filterType = 0;
5551 tANI_U8 *value = command;
5552
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305553 ret = hdd_drv_cmd_validate(command, 21);
5554 if (ret)
5555 goto exit;
5556
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305557 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5558 value = value + 22;
5559
5560 /* Convert the value from ascii to integer */
5561 ret = kstrtou8(value, 10, &filterType);
5562 if (ret < 0)
5563 {
5564 /* If the input value is greater than max value of datatype,
5565 * then also kstrtou8 fails
5566 */
5567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5568 "%s: kstrtou8 failed range ", __func__);
5569 ret = -EINVAL;
5570 goto exit;
5571 }
5572
5573 if (filterType != 0 && filterType != 1)
5574 {
5575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5576 "%s: Accepted Values are 0 and 1 ", __func__);
5577 ret = -EINVAL;
5578 goto exit;
5579 }
5580 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5581 pAdapter->sessionId);
5582 }
5583#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305584 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5585 {
Kiet Lamad161252014-07-22 11:23:32 -07005586 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305587 int ret;
5588
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305589 ret = hdd_drv_cmd_validate(command, 10);
5590 if (ret)
5591 goto exit;
5592
Kiet Lamad161252014-07-22 11:23:32 -07005593 dhcpPhase = command + 11;
5594 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305595 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005597 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305598
5599 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005600
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305601 ret = wlan_hdd_scan_abort(pAdapter);
5602 if (ret < 0)
5603 {
5604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5605 FL("failed to abort existing scan %d"), ret);
5606 }
5607
Kiet Lamad161252014-07-22 11:23:32 -07005608 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5609 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305610 }
Kiet Lamad161252014-07-22 11:23:32 -07005611 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305612 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005614 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305615
5616 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005617
5618 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5619 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305620 }
5621 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005622 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5623 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305624 hddLog(LOG1,
5625 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305626 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005627 }
5628 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5629 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305630 hddLog(LOG1,
5631 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305632 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005633 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305634 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5635 {
5636 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5637 char extra[32];
5638 tANI_U8 len = 0;
5639
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305640 memset(extra, 0, sizeof(extra));
5641 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305642 len = VOS_MIN(priv_data.total_len, len + 1);
5643 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5645 "%s: failed to copy data to user buffer", __func__);
5646 ret = -EFAULT;
5647 goto exit;
5648 }
5649 ret = len;
5650 }
5651 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5652 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305653 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305654 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305655 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5656 {
5657 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5658 char extra[32];
5659 tANI_U8 len = 0;
5660
5661 if (hdd_drv_cmd_validate(command, 15)) {
5662 hddLog(LOGE, FL("Invalid driver command"));
5663 return -EINVAL;
5664 }
5665
5666 memset(extra, 0, sizeof(extra));
5667 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5668 sizeof(extra), &len);
5669 len = VOS_MIN(priv_data.total_len, len + 1);
5670 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5671 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5672 ret = -EFAULT;
5673 goto exit;
5674 }
5675 ret = len;
5676 }
5677 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5678 {
5679 if (hdd_drv_cmd_validate(command, 15)) {
5680 hddLog(LOGE, FL("Invalid driver command"));
5681 return -EINVAL;
5682 }
5683 ret = hdd_btc_set_dwell_time(pAdapter, command);
5684 }
5685#ifdef WLAN_AP_STA_CONCURRENCY
5686 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5687 {
5688 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5689 char extra[32];
5690 tANI_U8 len = 0;
5691
5692 if (hdd_drv_cmd_validate(command, 16)) {
5693 hddLog(LOGE, FL("Invalid driver command"));
5694 return -EINVAL;
5695 }
5696
5697 memset(extra, 0, sizeof(extra));
5698 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5699 sizeof(extra), &len);
5700 len = VOS_MIN(priv_data.total_len, len + 1);
5701 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5702 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5703 ret = -EFAULT;
5704 goto exit;
5705 }
5706 ret = len;
5707 }
5708 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5709 {
5710 if (hdd_drv_cmd_validate(command, 16)) {
5711 hddLog(LOGE, FL("Invalid driver command"));
5712 return -EINVAL;
5713 }
5714 ret = hdd_conc_set_dwell_time(pAdapter, command);
5715 }
5716#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005717 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5718 {
5719 tANI_U8 filterType = 0;
5720 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305721
5722 ret = hdd_drv_cmd_validate(command, 8);
5723 if (ret)
5724 goto exit;
5725
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005726 value = command + 9;
5727
5728 /* Convert the value from ascii to integer */
5729 ret = kstrtou8(value, 10, &filterType);
5730 if (ret < 0)
5731 {
5732 /* If the input value is greater than max value of datatype,
5733 * then also kstrtou8 fails
5734 */
5735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5736 "%s: kstrtou8 failed range ", __func__);
5737 ret = -EINVAL;
5738 goto exit;
5739 }
5740 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5741 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5742 {
5743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5744 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5745 " 2-Sink ", __func__);
5746 ret = -EINVAL;
5747 goto exit;
5748 }
5749 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5750 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305751 pScanInfo = &pHddCtx->scan_info;
5752 if (filterType && pScanInfo != NULL &&
5753 pHddCtx->scan_info.mScanPending)
5754 {
5755 /*Miracast Session started. Abort Scan */
5756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5757 "%s, Aborting Scan For Miracast",__func__);
5758 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5759 eCSR_SCAN_ABORT_DEFAULT);
5760 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005761 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305762 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005763 }
Leo Chang614d2072013-08-22 14:59:44 -07005764 else if (strncmp(command, "SETMCRATE", 9) == 0)
5765 {
Leo Chang614d2072013-08-22 14:59:44 -07005766 tANI_U8 *value = command;
5767 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005768 tSirRateUpdateInd *rateUpdate;
5769 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005770
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305771 ret = hdd_drv_cmd_validate(command, 9);
5772 if (ret)
5773 goto exit;
5774
Leo Chang614d2072013-08-22 14:59:44 -07005775 /* Only valid for SAP mode */
5776 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5777 {
5778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5779 "%s: SAP mode is not running", __func__);
5780 ret = -EFAULT;
5781 goto exit;
5782 }
5783
5784 /* Move pointer to ahead of SETMCRATE<delimiter> */
5785 /* input value is in units of hundred kbps */
5786 value = value + 10;
5787 /* Convert the value from ascii to integer, decimal base */
5788 ret = kstrtouint(value, 10, &targetRate);
5789
Leo Chang1f98cbd2013-10-17 15:03:52 -07005790 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5791 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005792 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005793 hddLog(VOS_TRACE_LEVEL_ERROR,
5794 "%s: SETMCRATE indication alloc fail", __func__);
5795 ret = -EFAULT;
5796 goto exit;
5797 }
5798 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5799
5800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5801 "MC Target rate %d", targetRate);
5802 /* Ignore unicast */
5803 rateUpdate->ucastDataRate = -1;
5804 rateUpdate->mcastDataRate24GHz = targetRate;
5805 rateUpdate->mcastDataRate5GHz = targetRate;
5806 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5807 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5808 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5809 if (eHAL_STATUS_SUCCESS != status)
5810 {
5811 hddLog(VOS_TRACE_LEVEL_ERROR,
5812 "%s: SET_MC_RATE failed", __func__);
5813 vos_mem_free(rateUpdate);
5814 ret = -EFAULT;
5815 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005816 }
5817 }
jge35567202017-06-21 16:39:38 +08005818 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5819 {
5820 int status;
5821 int txPower;
5822 eHalStatus smeStatus;
5823 tANI_U8 *value = command;
5824 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5825 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5826
5827 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5828 if (status)
5829 {
5830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5831 "Invalid MAXTXPOWER command ");
5832 ret = -EINVAL;
5833 goto exit;
5834 }
5835
5836 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5837 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5838 txPower, MAC_ADDR_ARRAY(selfMac),
5839 MAC_ADDR_ARRAY(bssid));
5840 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5841 bssid, selfMac, txPower) ;
5842 if( smeStatus != eHAL_STATUS_SUCCESS )
5843 {
5844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5845 __func__);
5846 ret = -EINVAL;
5847 goto exit;
5848 }
5849
5850 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5851 __func__);
5852 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305853#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005854 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305855 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005856 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305857 }
5858#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305859#ifdef WLAN_FEATURE_RMC
5860 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5861 (WLAN_HDD_IBSS == pAdapter->device_mode))
5862 {
5863 int i = 0;
5864 tANI_U8 *ibss_ie;
5865 tANI_U32 command_len;
5866 tANI_U8 *value = command;
5867 tHalHandle hHal = pHddCtx->hHal;
5868 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5869 tANI_U32 ibss_ie_length;
5870 tANI_U32 len, present;
5871 tANI_U8 *addIE;
5872 tANI_U8 *addIEData;
5873
5874 hddLog(LOG1,
5875 FL(" received command %s"),((char *) value));
5876 /* validate argument of command */
5877 if (strlen(value) <= 21)
5878 {
5879 hddLog(LOGE,
5880 FL("No arguements in command length %zu"), strlen(value));
5881 ret = -EFAULT;
5882 goto exit;
5883 }
5884
5885 /* moving to arguments of commands */
5886 value = value + 21;
5887 command_len = strlen(value);
5888
5889 /* oui_data can't be less than 3 bytes */
5890 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5891 {
5892 hddLog(LOGE,
5893 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5894 command_len);
5895 ret = -EFAULT;
5896 goto exit;
5897 }
5898 ibss_ie = vos_mem_malloc(command_len);
5899 if (!ibss_ie) {
5900 hddLog(LOGE,
5901 FL("Could not allocate memory for command length %d"),
5902 command_len);
5903 ret = -ENOMEM;
5904 goto exit;
5905 }
5906 vos_mem_zero(ibss_ie, command_len);
5907
5908 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5909 command_len);
5910 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5911 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5912 value, ibss_ie_length);
5913 ret = -EFAULT;
5914 vos_mem_free(ibss_ie);
5915 goto exit;
5916 }
5917
5918 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5919 while (i < ibss_ie_length)
5920 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5921
5922 /* Populate Vendor IE in Beacon */
5923 if ((ccmCfgGetInt(hHal,
5924 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5925 &present)) != eHAL_STATUS_SUCCESS)
5926 {
5927 hddLog(LOGE,
5928 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5929 ret = -EFAULT;
5930 vos_mem_free(ibss_ie);
5931 goto exit;
5932 }
5933
5934 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5935 if (!addIE) {
5936 hddLog(LOGE,
5937 FL("Could not allocate memory for command length %d"),
5938 command_len);
5939 vos_mem_free(ibss_ie);
5940 ret = -ENOMEM;
5941 goto exit;
5942 }
5943 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5944
5945 if (present)
5946 {
5947 if ((wlan_cfgGetStrLen(pMac,
5948 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5949 {
5950 hddLog(LOGE,
5951 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5952 ret = -EFAULT;
5953 vos_mem_free(ibss_ie);
5954 vos_mem_free(addIE);
5955 goto exit;
5956 }
5957
5958 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5959 ((len + ibss_ie_length) <=
5960 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5961 {
5962 if ((ccmCfgGetStr(hHal,
5963 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5964 != eHAL_STATUS_SUCCESS)
5965 {
5966 hddLog(LOGE,
5967 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5968 ret = -EFAULT;
5969 vos_mem_free(ibss_ie);
5970 vos_mem_free(addIE);
5971 goto exit;
5972 }
5973 else
5974 {
5975 /* Curruntly only WPA IE is added before Vendor IE
5976 * so we can blindly place the Vendor IE after WPA
5977 * IE. If no WPA IE found replace all with Vendor IE.
5978 */
5979 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5980 }
5981 }
5982 else
5983 {
5984 hddLog(LOGE,
5985 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5986 len, ibss_ie_length);
5987 ret = -EFAULT;
5988 vos_mem_free(addIE);
5989 vos_mem_free(ibss_ie);
5990 goto exit;
5991 }
5992 }
5993 else {
5994 len = 0;
5995 }
5996
5997 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5998 len += ibss_ie_length;
5999
6000 if (ccmCfgSetStr(hHal,
6001 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
6002 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6003 {
6004 hddLog(LOGE,
6005 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
6006 ret = -EFAULT;
6007 vos_mem_free(ibss_ie);
6008 vos_mem_free(addIE);
6009 goto exit;
6010 }
6011 vos_mem_free(addIE);
6012 if (ccmCfgSetInt(hHal,
6013 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6014 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6015 {
6016 hddLog(LOGE,
6017 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6018 ret = -EFAULT;
6019 vos_mem_free(ibss_ie);
6020 goto exit;
6021 }
6022
6023 /* Populate Vendor IE in probe resp */
6024 if ((ccmCfgGetInt(hHal,
6025 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6026 &present)) != eHAL_STATUS_SUCCESS)
6027 {
6028 hddLog(LOGE,
6029 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6030 ret = -EFAULT;
6031 vos_mem_free(ibss_ie);
6032 goto exit;
6033 }
6034
6035 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6036 if (!addIEData) {
6037 hddLog(LOGE,
6038 FL("Could not allocate memory for command length %d"),
6039 command_len);
6040 vos_mem_free(ibss_ie);
6041 ret = -ENOMEM;
6042 goto exit;
6043 }
6044 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6045
6046 if (present) {
6047 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6048 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6049 hddLog(LOGE,
6050 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6051 ret = -EFAULT;
6052 vos_mem_free(ibss_ie);
6053 vos_mem_free(addIEData);
6054 goto exit;
6055 }
6056 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6057 (ibss_ie_length + len) <=
6058 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6059
6060 if ((ccmCfgGetStr(hHal,
6061 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6062 != eHAL_STATUS_SUCCESS) {
6063 hddLog(LOGE,
6064 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6065 ret = -EFAULT;
6066 vos_mem_free(ibss_ie);
6067 vos_mem_free(addIEData);
6068 goto exit;
6069 }
6070 else {
6071 /* Curruntly only WPA IE is added before Vendor IE
6072 * so we can blindly place the Vendor IE after WPA
6073 * IE. If no WPA IE found replace all with Vendor IE.
6074 */
6075 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6076 }
6077 }
6078 else
6079 {
6080 hddLog(LOGE,
6081 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6082 len, ibss_ie_length);
6083 ret = -EFAULT;
6084 vos_mem_free(addIEData);
6085 vos_mem_free(ibss_ie);
6086 goto exit;
6087 }
6088 } /* probe rsp ADD IE present */
6089 else {
6090 /* probe rsp add IE is not present */
6091 len = 0;
6092 }
6093
6094 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6095 len += ibss_ie_length;
6096
6097 vos_mem_free(ibss_ie);
6098
6099 if (ccmCfgSetStr(hHal,
6100 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6101 (tANI_U8*)(addIEData),
6102 len, NULL,
6103 eANI_BOOLEAN_FALSE)
6104 == eHAL_STATUS_FAILURE) {
6105 hddLog(LOGE,
6106 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6107 ret = -EFAULT;
6108 vos_mem_free(addIEData);
6109 goto exit;
6110 }
6111 vos_mem_free(addIEData);
6112 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6113 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6114 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6115 {
6116 hddLog(LOGE,
6117 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6118 ret = -EFAULT;
6119 goto exit;
6120 }
6121 }
6122 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6123 {
6124 tANI_U8 *value = command;
6125 tANI_U8 ucRmcEnable = 0;
6126 int status;
6127
6128 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6129 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6130 {
6131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6132 "Received SETRMCENABLE command in invalid mode %d "
6133 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6134 pAdapter->device_mode);
6135 ret = -EINVAL;
6136 goto exit;
6137 }
6138
6139 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6140 if (status)
6141 {
6142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6143 "Invalid SETRMCENABLE command ");
6144 ret = -EINVAL;
6145 goto exit;
6146 }
6147
6148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6149 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6150
6151 if (TRUE == ucRmcEnable)
6152 {
6153 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6154 pAdapter->sessionId );
6155 }
6156 else if(FALSE == ucRmcEnable)
6157 {
6158 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6159 pAdapter->sessionId );
6160 }
6161 else
6162 {
6163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6164 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6165 ret = -EINVAL;
6166 goto exit;
6167 }
6168
6169 if (VOS_STATUS_SUCCESS != status)
6170 {
6171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6172 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6173 status);
6174 ret = -EINVAL;
6175 goto exit;
6176 }
6177 }
6178 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6179 {
6180 tANI_U8 *value = command;
6181 tANI_U32 uActionPeriod = 0;
6182 int status;
6183
6184 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6185 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6186 {
6187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6188 "Received SETRMC command in invalid mode %d "
6189 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6190 pAdapter->device_mode);
6191 ret = -EINVAL;
6192 goto exit;
6193 }
6194
6195 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6196 if (status)
6197 {
6198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "Invalid SETRMCACTIONPERIOD command ");
6200 ret = -EINVAL;
6201 goto exit;
6202 }
6203
6204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6205 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6206
6207 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6208 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6209 {
6210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6211 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6212 ret = -EINVAL;
6213 goto exit;
6214 }
6215
6216 }
6217 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6218 {
6219 /* Peer Info All Command */
6220 int status = eHAL_STATUS_SUCCESS;
6221 hdd_station_ctx_t *pHddStaCtx = NULL;
6222 char *extra = NULL;
6223 int idx = 0, length = 0;
6224 v_MACADDR_t *macAddr;
6225 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6226
6227 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6228 {
6229 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6230 }
6231 else
6232 {
6233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6234 "%s: pAdapter is not valid for this device mode",
6235 __func__);
6236 ret = -EINVAL;
6237 goto exit;
6238 }
6239
6240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6241 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6242
6243
6244 /* Handle the command */
6245 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6246 if (VOS_STATUS_SUCCESS == status)
6247 {
6248 /* The variable extra needed to be allocated on the heap since
6249 * amount of memory required to copy the data for 32 devices
6250 * exceeds the size of 1024 bytes of default stack size. On
6251 * 64 bit devices, the default max stack size of 2048 bytes
6252 */
6253 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6254
6255 if (NULL == extra)
6256 {
6257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6258 "%s:kmalloc failed", __func__);
6259 ret = -EINVAL;
6260 goto exit;
6261 }
6262
6263 /* Copy number of stations */
6264 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6265 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6266 numOfBytestoPrint = length;
6267 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6268 {
6269 macAddr =
6270 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6271 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6272 if (NULL != macAddr)
6273 {
6274 txRateMbps =
6275 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6276
6277 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6278 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6279 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6280 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6281 (int)txRateMbps,
6282 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6283 }
6284 else
6285 {
6286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6287 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6288 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6289 }
6290
6291 /*
6292 * VOS_TRACE() macro has limitation of 512 bytes for the print
6293 * buffer. Hence printing the data in two chunks. The first chunk
6294 * will have the data for 16 devices and the second chunk will
6295 * have the rest.
6296 */
6297 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6298 {
6299 numOfBytestoPrint = length;
6300 }
6301 }
6302
6303 /*
6304 * Copy the data back into buffer, if the data to copy is
6305 * morethan 512 bytes than we will split the data and do
6306 * it in two shots
6307 */
6308 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6309 {
6310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6311 "%s: Copy into user data buffer failed ", __func__);
6312 ret = -EFAULT;
6313 kfree(extra);
6314 goto exit;
6315 }
6316 priv_data.buf[numOfBytestoPrint] = '\0';
6317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6318 "%s", priv_data.buf);
6319
6320 if (length > numOfBytestoPrint)
6321 {
6322 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6323 extra + numOfBytestoPrint,
6324 length - numOfBytestoPrint + 1))
6325 {
6326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6327 "%s: Copy into user data buffer failed ", __func__);
6328 ret = -EFAULT;
6329 kfree(extra);
6330 goto exit;
6331 }
6332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6333 "%s", &priv_data.buf[numOfBytestoPrint]);
6334 }
6335
6336 /* Free temporary buffer */
6337 kfree(extra);
6338 }
6339
6340 else
6341 {
6342 /* Command failed, log error */
6343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6344 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6345 __func__, status);
6346 ret = -EINVAL;
6347 goto exit;
6348 }
6349 ret = 0;
6350 }
6351 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6352 {
6353 /* Peer Info <Peer Addr> command */
6354 tANI_U8 *value = command;
6355 VOS_STATUS status;
6356 hdd_station_ctx_t *pHddStaCtx = NULL;
6357 char extra[128] = { 0 };
6358 v_U32_t length = 0;
6359 v_U8_t staIdx = 0;
6360 v_U32_t txRateMbps = 0;
6361 v_MACADDR_t peerMacAddr;
6362
6363 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6364 {
6365 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6366 }
6367 else
6368 {
6369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6370 "%s: pAdapter is not valid for this device mode",
6371 __func__);
6372 ret = -EINVAL;
6373 goto exit;
6374 }
6375
6376 /* if there are no peers, no need to continue with the command */
6377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6378 "%s: Received GETIBSSPEERINFO Command", __func__);
6379
6380 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6381 {
6382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6383 "%s:No IBSS Peers coalesced", __func__);
6384 ret = -EINVAL;
6385 goto exit;
6386 }
6387
6388 /* Parse the incoming command buffer */
6389 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6390 if (VOS_STATUS_SUCCESS != status)
6391 {
6392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6393 "%s: Invalid GETIBSSPEERINFO command", __func__);
6394 ret = -EINVAL;
6395 goto exit;
6396 }
6397
6398 /* Get station index for the peer mac address */
6399 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6400
6401 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6402 {
6403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6404 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6405 ret = -EINVAL;
6406 goto exit;
6407 }
6408
6409 /* Handle the command */
6410 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6411 if (VOS_STATUS_SUCCESS == status)
6412 {
6413 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6414 txRateMbps = (txRate * 500 * 1000)/1000000;
6415
6416 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6417 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6418
6419 /* Copy the data back into buffer */
6420 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6421 {
6422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6423 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6424 __func__);
6425 ret = -EFAULT;
6426 goto exit;
6427 }
6428 }
6429 else
6430 {
6431 /* Command failed, log error */
6432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6433 "%s: GETIBSSPEERINFO command failed with status code %d",
6434 __func__, status);
6435 ret = -EINVAL;
6436 goto exit;
6437 }
6438
6439 /* Success ! */
6440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6441 "%s", priv_data.buf);
6442 ret = 0;
6443 }
6444 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6445 {
6446 tANI_U8 *value = command;
6447 tANI_U32 uRate = 0;
6448 tTxrateinfoflags txFlags = 0;
6449 tSirRateUpdateInd *rateUpdateParams;
6450 int status;
6451
6452 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6453 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6454 {
6455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6456 "Received SETRMCTXRATE command in invalid mode %d "
6457 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6458 pAdapter->device_mode);
6459 ret = -EINVAL;
6460 goto exit;
6461 }
6462
6463 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6464 if (status)
6465 {
6466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6467 "Invalid SETRMCTXRATE command ");
6468 ret = -EINVAL;
6469 goto exit;
6470 }
6471
6472 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6473 if (NULL == rateUpdateParams)
6474 {
6475 ret = -EINVAL;
6476 goto exit;
6477 }
6478
6479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6480 "%s: uRate %d ", __func__, uRate);
6481
6482 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6483
6484 /* -1 implies ignore this param */
6485 rateUpdateParams->ucastDataRate = -1;
6486
6487 /*
6488 * Fill the user specifieed RMC rate param
6489 * and the derived tx flags.
6490 */
6491 rateUpdateParams->rmcDataRate = uRate;
6492 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6493
6494 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6495 }
6496 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6497 {
6498 char *value;
6499 tANI_U8 tx_fail_count = 0;
6500 tANI_U16 pid = 0;
6501
6502 value = command;
6503
6504 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6505
6506 if (0 != ret)
6507 {
6508 hddLog(VOS_TRACE_LEVEL_INFO,
6509 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6510 __func__);
6511 goto exit;
6512 }
6513
6514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6515 __func__, tx_fail_count, pid);
6516
6517 if (0 == tx_fail_count)
6518 {
6519 // Disable TX Fail Indication
6520 if (eHAL_STATUS_SUCCESS ==
6521 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6522 tx_fail_count,
6523 NULL))
6524 {
6525 cesium_pid = 0;
6526 }
6527 else
6528 {
6529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6530 "%s: failed to disable TX Fail Event ", __func__);
6531 ret = -EINVAL;
6532 }
6533 }
6534 else
6535 {
6536 if (eHAL_STATUS_SUCCESS ==
6537 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6538 tx_fail_count,
6539 (void*)hdd_tx_fail_ind_callback))
6540 {
6541 cesium_pid = pid;
6542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6543 "%s: Registered Cesium pid %u", __func__,
6544 cesium_pid);
6545 }
6546 else
6547 {
6548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6549 "%s: Failed to enable TX Fail Monitoring", __func__);
6550 ret = -EINVAL;
6551 }
6552 }
6553 }
6554
6555#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006556#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006557 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6558 {
6559 tANI_U8 *value = command;
6560 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6561 tANI_U8 numChannels = 0;
6562 eHalStatus status = eHAL_STATUS_SUCCESS;
6563
6564 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6565 if (eHAL_STATUS_SUCCESS != status)
6566 {
6567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6568 "%s: Failed to parse channel list information", __func__);
6569 ret = -EINVAL;
6570 goto exit;
6571 }
6572
6573 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6574 {
6575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6576 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6577 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6578 ret = -EINVAL;
6579 goto exit;
6580 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006581 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006582 ChannelList,
6583 numChannels);
6584 if (eHAL_STATUS_SUCCESS != status)
6585 {
6586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6587 "%s: Failed to update channel list information", __func__);
6588 ret = -EINVAL;
6589 goto exit;
6590 }
6591 }
6592 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6593 {
6594 tANI_U8 *value = command;
6595 char extra[128] = {0};
6596 int len = 0;
6597 tANI_U8 tid = 0;
6598 hdd_station_ctx_t *pHddStaCtx = NULL;
6599 tAniTrafStrmMetrics tsmMetrics;
6600 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6601
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306602 ret = hdd_drv_cmd_validate(command, 11);
6603 if (ret)
6604 goto exit;
6605
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006606 /* if not associated, return error */
6607 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6608 {
6609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6610 ret = -EINVAL;
6611 goto exit;
6612 }
6613
6614 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6615 value = value + 12;
6616 /* Convert the value from ascii to integer */
6617 ret = kstrtou8(value, 10, &tid);
6618 if (ret < 0)
6619 {
6620 /* If the input value is greater than max value of datatype, then also
6621 kstrtou8 fails */
6622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6623 "%s: kstrtou8 failed range [%d - %d]", __func__,
6624 TID_MIN_VALUE,
6625 TID_MAX_VALUE);
6626 ret = -EINVAL;
6627 goto exit;
6628 }
6629
6630 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6631 {
6632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6633 "tid value %d is out of range"
6634 " (Min: %d Max: %d)", tid,
6635 TID_MIN_VALUE,
6636 TID_MAX_VALUE);
6637 ret = -EINVAL;
6638 goto exit;
6639 }
6640
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6642 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6643
6644 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6645 {
6646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6647 "%s: failed to get tsm stats", __func__);
6648 ret = -EFAULT;
6649 goto exit;
6650 }
6651
6652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6653 "UplinkPktQueueDly(%d)\n"
6654 "UplinkPktQueueDlyHist[0](%d)\n"
6655 "UplinkPktQueueDlyHist[1](%d)\n"
6656 "UplinkPktQueueDlyHist[2](%d)\n"
6657 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306658 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006659 "UplinkPktLoss(%d)\n"
6660 "UplinkPktCount(%d)\n"
6661 "RoamingCount(%d)\n"
6662 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6663 tsmMetrics.UplinkPktQueueDlyHist[0],
6664 tsmMetrics.UplinkPktQueueDlyHist[1],
6665 tsmMetrics.UplinkPktQueueDlyHist[2],
6666 tsmMetrics.UplinkPktQueueDlyHist[3],
6667 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6668 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6669
6670 /* Output TSM stats is of the format
6671 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6672 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006673 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006674 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6675 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6676 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6677 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6678 tsmMetrics.RoamingDly);
6679
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306680 len = VOS_MIN(priv_data.total_len, len + 1);
6681 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6683 "%s: failed to copy data to user buffer", __func__);
6684 ret = -EFAULT;
6685 goto exit;
6686 }
6687 }
6688 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6689 {
6690 tANI_U8 *value = command;
6691 tANI_U8 *cckmIe = NULL;
6692 tANI_U8 cckmIeLen = 0;
6693 eHalStatus status = eHAL_STATUS_SUCCESS;
6694
6695 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6696 if (eHAL_STATUS_SUCCESS != status)
6697 {
6698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6699 "%s: Failed to parse cckm ie data", __func__);
6700 ret = -EINVAL;
6701 goto exit;
6702 }
6703
6704 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6705 {
6706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6707 "%s: CCKM Ie input length is more than max[%d]", __func__,
6708 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006709 vos_mem_free(cckmIe);
6710 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006711 ret = -EINVAL;
6712 goto exit;
6713 }
6714 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006715 vos_mem_free(cckmIe);
6716 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006717 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006718 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6719 {
6720 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006721 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006722 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006723
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006724 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006725 if (eHAL_STATUS_SUCCESS != status)
6726 {
6727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006728 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006729 ret = -EINVAL;
6730 goto exit;
6731 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006732 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6734 hdd_indicateEseBcnReportNoResults (pAdapter,
6735 eseBcnReq.bcnReq[0].measurementToken,
6736 0x02, //BIT(1) set for measurement done
6737 0); // no BSS
6738 goto exit;
6739 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006740
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006741 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6742 if (eHAL_STATUS_SUCCESS != status)
6743 {
6744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6745 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6746 ret = -EINVAL;
6747 goto exit;
6748 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006749 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006750#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306751 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6752 {
6753 eHalStatus status;
6754 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306755 void *cookie;
6756 struct hdd_request *request;
6757 struct bcn_miss_rate_priv *priv;
6758 static const struct hdd_request_params params = {
6759 .priv_size = sizeof(*priv),
6760 .timeout_ms = WLAN_WAIT_TIME_STATS,
6761 };
c_hpothu92367912014-05-01 15:18:17 +05306762
6763 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6764
6765 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6766 {
6767 hddLog(VOS_TRACE_LEVEL_WARN,
6768 FL("GETBCNMISSRATE: STA is not in connected state"));
6769 ret = -1;
6770 goto exit;
6771 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306772 request = hdd_request_alloc(&params);
6773 if (!request) {
6774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6775 ret = -ENOMEM;
6776 goto exit;
6777 }
6778 cookie = hdd_request_cookie(request);
6779 priv = hdd_request_priv(request);
6780 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306781
6782 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6783 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306784 (void *)get_bcn_miss_rate_cb,
6785 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306786 if( eHAL_STATUS_SUCCESS != status)
6787 {
6788 hddLog(VOS_TRACE_LEVEL_INFO,
6789 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6790 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306791 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306792 }
6793
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306794 ret = hdd_request_wait_for_response(request);
6795 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306796 {
6797 hddLog(VOS_TRACE_LEVEL_ERROR,
6798 FL("failed to wait on bcnMissRateComp %d"), ret);
6799
c_hpothu92367912014-05-01 15:18:17 +05306800 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306801 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306802 }
6803
6804 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306805 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306806
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306807 if (priv->bcn_miss_rate == -1) {
6808 ret = -EFAULT;
6809 goto free_bcn_miss_rate_req;
6810 }
6811
6812 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6813 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306814 if (copy_to_user(priv_data.buf, &buf, len + 1))
6815 {
6816 hddLog(VOS_TRACE_LEVEL_ERROR,
6817 "%s: failed to copy data to user buffer", __func__);
6818 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306819 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306820 }
6821 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306822
6823free_bcn_miss_rate_req:
6824 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306825 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306826#ifdef FEATURE_WLAN_TDLS
6827 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6828 tANI_U8 *value = command;
6829 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306830
6831 ret = hdd_drv_cmd_validate(command, 26);
6832 if (ret)
6833 goto exit;
6834
Atul Mittal87ec2422014-09-24 13:12:50 +05306835 /* Move pointer to ahead of TDLSOFFCH*/
6836 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306837 if (!(sscanf(value, "%d", &set_value))) {
6838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6839 FL("No input identified"));
6840 ret = -EINVAL;
6841 goto exit;
6842 }
6843
Atul Mittal87ec2422014-09-24 13:12:50 +05306844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6845 "%s: Tdls offchannel offset:%d",
6846 __func__, set_value);
6847 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6848 if (ret < 0)
6849 {
6850 ret = -EINVAL;
6851 goto exit;
6852 }
6853
6854 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6855 tANI_U8 *value = command;
6856 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306857
6858 ret = hdd_drv_cmd_validate(command, 18);
6859 if (ret)
6860 goto exit;
6861
Atul Mittal87ec2422014-09-24 13:12:50 +05306862 /* Move pointer to ahead of tdlsoffchnmode*/
6863 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306864 ret = sscanf(value, "%d", &set_value);
6865 if (ret != 1) {
6866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6867 FL("No input identified"));
6868 ret = -EINVAL;
6869 goto exit;
6870 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6872 "%s: Tdls offchannel mode:%d",
6873 __func__, set_value);
6874 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6875 if (ret < 0)
6876 {
6877 ret = -EINVAL;
6878 goto exit;
6879 }
6880 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6881 tANI_U8 *value = command;
6882 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306883
6884 ret = hdd_drv_cmd_validate(command, 14);
6885 if (ret)
6886 goto exit;
6887
Atul Mittal87ec2422014-09-24 13:12:50 +05306888 /* Move pointer to ahead of TDLSOFFCH*/
6889 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306890 ret = sscanf(value, "%d", &set_value);
6891 if (ret != 1) {
6892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6893 "Wrong value is given for hdd_set_tdls_offchannel");
6894 ret = -EINVAL;
6895 goto exit;
6896 }
6897
Atul Mittal87ec2422014-09-24 13:12:50 +05306898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6899 "%s: Tdls offchannel num: %d",
6900 __func__, set_value);
6901 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6902 if (ret < 0)
6903 {
6904 ret = -EINVAL;
6905 goto exit;
6906 }
6907 }
6908#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306909 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6910 {
6911 eHalStatus status;
6912 char *buf = NULL;
6913 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306914 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6915 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306916 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306917 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306918 void *cookie;
6919 struct hdd_request *request;
6920 struct fw_stats_priv *priv;
6921 static const struct hdd_request_params params = {
6922 .priv_size = sizeof(*priv),
6923 .timeout_ms = WLAN_WAIT_TIME_STATS,
6924 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306925
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306926 ret = hdd_drv_cmd_validate(command, 10);
6927 if (ret)
6928 goto exit;
6929
6930 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306931 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6932 if (!IS_FEATURE_FW_STATS_ENABLE)
6933 {
6934 hddLog(VOS_TRACE_LEVEL_INFO,
6935 FL("Get Firmware stats feature not supported"));
6936 ret = -EINVAL;
6937 goto exit;
6938 }
6939
6940 if (FW_STATS_MAX <= stats || 0 >= stats)
6941 {
6942 hddLog(VOS_TRACE_LEVEL_INFO,
6943 FL(" stats %d not supported"),stats);
6944 ret = -EINVAL;
6945 goto exit;
6946 }
6947
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306948 request = hdd_request_alloc(&params);
6949 if (!request) {
6950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6951 ret = -ENOMEM;
6952 goto exit;
6953 }
6954 cookie = hdd_request_cookie(request);
6955
Satyanarayana Dash72806012014-12-02 14:30:08 +05306956 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306957 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306958 if (eHAL_STATUS_SUCCESS != status)
6959 {
6960 hddLog(VOS_TRACE_LEVEL_ERROR,
6961 FL(" fail to post WDA cmd status = %d"), status);
6962 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306963 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306964 goto exit;
6965 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306966 ret = hdd_request_wait_for_response(request);
6967 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306968 {
6969 hddLog(VOS_TRACE_LEVEL_ERROR,
6970 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306971 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306972 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306973 goto exit;
6974 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306975
6976 priv = hdd_request_priv(request);
6977 fw_stats_result = priv->fw_stats;
6978 fwStatsRsp->type = 0;
6979 if (NULL != fw_stats_result)
6980 {
6981 switch (fw_stats_result->type )
6982 {
6983 case FW_UBSP_STATS:
6984 {
6985 tSirUbspFwStats *stats =
6986 &fwStatsRsp->fwStatsData.ubspStats;
6987 memcpy(fwStatsRsp, fw_stats_result,
6988 sizeof(tSirFwStatsResult));
6989 hddLog(VOS_TRACE_LEVEL_INFO,
6990 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6991 stats->ubsp_enter_cnt,
6992 stats->ubsp_jump_ddr_cnt);
6993 }
6994 break;
6995
6996 default:
6997 {
6998 hddLog(VOS_TRACE_LEVEL_ERROR,
6999 FL("No handling for stats type %d"),
7000 fw_stats_result->type);
7001 }
7002 }
7003 }
7004 hdd_request_put(request);
7005
Satyanarayana Dash72806012014-12-02 14:30:08 +05307006 if (fwStatsRsp->type)
7007 {
7008 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
7009 if (!buf)
7010 {
7011 hddLog(VOS_TRACE_LEVEL_ERROR,
7012 FL(" failed to allocate memory"));
7013 ret = -ENOMEM;
7014 goto exit;
7015 }
7016 switch( fwStatsRsp->type )
7017 {
7018 case FW_UBSP_STATS:
7019 {
7020 len = snprintf(buf, FW_STATE_RSP_LEN,
7021 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307022 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7023 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307024 }
7025 break;
7026 default:
7027 {
7028 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7029 ret = -EFAULT;
7030 kfree(buf);
7031 goto exit;
7032 }
7033 }
7034 if (copy_to_user(priv_data.buf, buf, len + 1))
7035 {
7036 hddLog(VOS_TRACE_LEVEL_ERROR,
7037 FL(" failed to copy data to user buffer"));
7038 ret = -EFAULT;
7039 kfree(buf);
7040 goto exit;
7041 }
7042 ret = len;
7043 kfree(buf);
7044 }
7045 else
7046 {
7047 hddLog(VOS_TRACE_LEVEL_ERROR,
7048 FL("failed to fetch the stats"));
7049 ret = -EFAULT;
7050 goto exit;
7051 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307052 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307053 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7054 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307055 ret = hdd_drv_cmd_validate(command, 15);
7056 if (ret)
7057 goto exit;
7058
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307059 /*
7060 * this command wld be called by user-space when it detects WLAN
7061 * ON after airplane mode is set. When APM is set, WLAN turns off.
7062 * But it can be turned back on. Otherwise; when APM is turned back
7063 * off, WLAN wld turn back on. So at that point the command is
7064 * expected to come down. 0 means disable, 1 means enable. The
7065 * constraint is removed when parameter 1 is set or different
7066 * country code is set
7067 */
7068 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7069 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307070 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7071 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307072 ret = hdd_drv_cmd_validate(command, 16);
7073 if (ret)
7074 goto exit;
7075
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307076 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7077 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307078 /*
7079 * command should be a string having format
7080 * SET_DISABLE_CHANNEL_LIST <num of channels>
7081 * <channels separated by spaces>
7082 */
7083 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7084 tANI_U8 *ptr = command;
7085 ret = hdd_drv_cmd_validate(command, 24);
7086 if (ret)
7087 goto exit;
7088
7089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7090 " Received Command to disable Channels %s",
7091 __func__);
7092 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7093 if (ret)
7094 goto exit;
7095 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307096 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307097 char extra[512] = {0};
7098 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307099
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307101 " Received Command to get disable Channels list %s",
7102 __func__);
7103
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307104 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7105 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7106 if (copied_length == 0) {
7107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307108 FL("disable channel list are not yet programed"));
7109 ret = -EINVAL;
7110 goto exit;
7111 }
7112
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307113 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7115 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307116 ret = -EFAULT;
7117 goto exit;
7118 }
7119
7120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7121 FL("data:%s"), extra);
7122 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007123 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307124 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7125 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7126 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307127 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7128 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 }
7131exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307132 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 if (command)
7134 {
7135 kfree(command);
7136 }
7137 return ret;
7138}
7139
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007140#ifdef CONFIG_COMPAT
7141static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7142{
7143 struct {
7144 compat_uptr_t buf;
7145 int used_len;
7146 int total_len;
7147 } compat_priv_data;
7148 hdd_priv_data_t priv_data;
7149 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007150
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007151 /*
7152 * Note that pAdapter and ifr have already been verified by caller,
7153 * and HDD context has also been validated
7154 */
7155 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7156 sizeof(compat_priv_data))) {
7157 ret = -EFAULT;
7158 goto exit;
7159 }
7160 priv_data.buf = compat_ptr(compat_priv_data.buf);
7161 priv_data.used_len = compat_priv_data.used_len;
7162 priv_data.total_len = compat_priv_data.total_len;
7163 ret = hdd_driver_command(pAdapter, &priv_data);
7164 exit:
7165 return ret;
7166}
7167#else /* CONFIG_COMPAT */
7168static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7169{
7170 /* will never be invoked */
7171 return 0;
7172}
7173#endif /* CONFIG_COMPAT */
7174
7175static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7176{
7177 hdd_priv_data_t priv_data;
7178 int ret = 0;
7179
7180 /*
7181 * Note that pAdapter and ifr have already been verified by caller,
7182 * and HDD context has also been validated
7183 */
7184 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7185 ret = -EFAULT;
7186 } else {
7187 ret = hdd_driver_command(pAdapter, &priv_data);
7188 }
7189 return ret;
7190}
7191
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307192int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007193{
7194 hdd_adapter_t *pAdapter;
7195 hdd_context_t *pHddCtx;
7196 int ret;
7197
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307198 ENTER();
7199
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007200 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7201 if (NULL == pAdapter) {
7202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7203 "%s: HDD adapter context is Null", __func__);
7204 ret = -ENODEV;
7205 goto exit;
7206 }
7207 if (dev != pAdapter->dev) {
7208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7209 "%s: HDD adapter/dev inconsistency", __func__);
7210 ret = -ENODEV;
7211 goto exit;
7212 }
7213
7214 if ((!ifr) || (!ifr->ifr_data)) {
7215 ret = -EINVAL;
7216 goto exit;
7217 }
7218
7219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7220 ret = wlan_hdd_validate_context(pHddCtx);
7221 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007222 ret = -EBUSY;
7223 goto exit;
7224 }
7225
7226 switch (cmd) {
7227 case (SIOCDEVPRIVATE + 1):
7228 if (is_compat_task())
7229 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7230 else
7231 ret = hdd_driver_ioctl(pAdapter, ifr);
7232 break;
7233 default:
7234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7235 __func__, cmd);
7236 ret = -EINVAL;
7237 break;
7238 }
7239 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307240 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007241 return ret;
7242}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007243
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307244int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7245{
7246 int ret;
7247
7248 vos_ssr_protect(__func__);
7249 ret = __hdd_ioctl(dev, ifr, cmd);
7250 vos_ssr_unprotect(__func__);
7251
7252 return ret;
7253}
7254
Katya Nigame7b69a82015-04-28 15:24:06 +05307255int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7256{
7257 return 0;
7258}
7259
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007260#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007261/**---------------------------------------------------------------------------
7262
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007263 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007264
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007265 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007266 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7267 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7268 <space>Scan Mode N<space>Meas Duration N
7269 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7270 then take N.
7271 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7272 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7273 This function does not take care of removing duplicate channels from the list
7274
7275 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007276 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007277
7278 \return - 0 for success non-zero for failure
7279
7280 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007281static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7282 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007283{
7284 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307285 uint8_t input = 0;
7286 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007287 int j = 0, i = 0, v = 0;
7288 char buf[32];
7289
7290 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7291 /*no argument after the command*/
7292 if (NULL == inPtr)
7293 {
7294 return -EINVAL;
7295 }
7296 /*no space after the command*/
7297 else if (SPACE_ASCII_VALUE != *inPtr)
7298 {
7299 return -EINVAL;
7300 }
7301
7302 /*removing empty spaces*/
7303 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7304
7305 /*no argument followed by spaces*/
7306 if ('\0' == *inPtr) return -EINVAL;
7307
7308 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007309 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007310 if (1 != v) return -EINVAL;
7311
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307312 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007313 if ( v < 0) return -EINVAL;
7314
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307315 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7316 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007317
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307318 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7319
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007320
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007321 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007322 {
7323 for (i = 0; i < 4; i++)
7324 {
7325 /*inPtr pointing to the beginning of first space after number of ie fields*/
7326 inPtr = strpbrk( inPtr, " " );
7327 /*no ie data after the number of ie fields argument*/
7328 if (NULL == inPtr) return -EINVAL;
7329
7330 /*removing empty space*/
7331 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7332
7333 /*no ie data after the number of ie fields argument and spaces*/
7334 if ( '\0' == *inPtr ) return -EINVAL;
7335
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007336 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007337 if (1 != v) return -EINVAL;
7338
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307339 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007340 if (v < 0) return -EINVAL;
7341
7342 switch (i)
7343 {
7344 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307345 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007346 {
7347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307348 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007349 return -EINVAL;
7350 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007351 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007352 break;
7353
7354 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307355 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007356 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7357 {
7358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307359 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007360 return -EINVAL;
7361 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007362 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007363 break;
7364
7365 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007366 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007367 {
7368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307369 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007370 return -EINVAL;
7371 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007372 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007373 break;
7374
7375 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307376 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7377 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007378 {
7379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307380 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007381 return -EINVAL;
7382 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007383 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007384 break;
7385 }
7386 }
7387 }
7388
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007389 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007390 {
7391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307392 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007393 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007394 pEseBcnReq->bcnReq[j].measurementToken,
7395 pEseBcnReq->bcnReq[j].channel,
7396 pEseBcnReq->bcnReq[j].scanMode,
7397 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007398 }
7399
7400 return VOS_STATUS_SUCCESS;
7401}
7402
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307403struct tsm_priv {
7404 tAniTrafStrmMetrics tsm_metrics;
7405};
7406
7407static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7408 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007409{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307410 struct hdd_request *request;
7411 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007412
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307413 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007414
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307415 request = hdd_request_get(context);
7416 if (!request) {
7417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7418 return;
7419 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007420
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307421 priv = hdd_request_priv(request);
7422 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007423
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307424 hdd_request_complete(request);
7425 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007426
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307427 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007428}
7429
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007430static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7431 tAniTrafStrmMetrics* pTsmMetrics)
7432{
7433 hdd_station_ctx_t *pHddStaCtx = NULL;
7434 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007435 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007436 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307437 int ret;
7438 void *cookie;
7439 struct hdd_request *request;
7440 struct tsm_priv *priv;
7441 static const struct hdd_request_params params = {
7442 .priv_size = sizeof(*priv),
7443 .timeout_ms = WLAN_WAIT_TIME_STATS,
7444 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007445
7446 if (NULL == pAdapter)
7447 {
7448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7449 return VOS_STATUS_E_FAULT;
7450 }
7451
7452 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7453 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7454
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307455 request = hdd_request_alloc(&params);
7456 if (!request) {
7457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7458 return VOS_STATUS_E_NOMEM;
7459 }
7460 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007461
7462 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307463 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007464 pHddStaCtx->conn_info.staId[ 0 ],
7465 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307466 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007467
7468 if (eHAL_STATUS_SUCCESS != hstatus)
7469 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7471 __func__);
7472 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007473 }
7474 else
7475 {
7476 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307477 ret = hdd_request_wait_for_response(request);
7478 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007479 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307480 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007481 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307482 } else {
7483 priv = hdd_request_priv(request);
7484 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007485 }
7486 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007487
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307488 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007489
Jeff Johnson72a40512013-12-19 10:14:15 -08007490 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007491}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007492#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007493
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007494#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007495void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7496{
7497 eCsrBand band = -1;
7498 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7499 switch (band)
7500 {
7501 case eCSR_BAND_ALL:
7502 *pBand = WLAN_HDD_UI_BAND_AUTO;
7503 break;
7504
7505 case eCSR_BAND_24:
7506 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7507 break;
7508
7509 case eCSR_BAND_5G:
7510 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7511 break;
7512
7513 default:
7514 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7515 *pBand = -1;
7516 break;
7517 }
7518}
7519
7520/**---------------------------------------------------------------------------
7521
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007522 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7523
7524 This function parses the send action frame data passed in the format
7525 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7526
Srinivas Girigowda56076852013-08-20 14:00:50 -07007527 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007528 \param - pTargetApBssid Pointer to target Ap bssid
7529 \param - pChannel Pointer to the Target AP channel
7530 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7531 \param - pBuf Pointer to data
7532 \param - pBufLen Pointer to data length
7533
7534 \return - 0 for success non-zero for failure
7535
7536 --------------------------------------------------------------------------*/
7537VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7538 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7539{
7540 tANI_U8 *inPtr = pValue;
7541 tANI_U8 *dataEnd;
7542 int tempInt;
7543 int j = 0;
7544 int i = 0;
7545 int v = 0;
7546 tANI_U8 tempBuf[32];
7547 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007548 /* 12 hexa decimal digits, 5 ':' and '\0' */
7549 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007550
7551 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7552 /*no argument after the command*/
7553 if (NULL == inPtr)
7554 {
7555 return -EINVAL;
7556 }
7557
7558 /*no space after the command*/
7559 else if (SPACE_ASCII_VALUE != *inPtr)
7560 {
7561 return -EINVAL;
7562 }
7563
7564 /*removing empty spaces*/
7565 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7566
7567 /*no argument followed by spaces*/
7568 if ('\0' == *inPtr)
7569 {
7570 return -EINVAL;
7571 }
7572
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007573 v = sscanf(inPtr, "%17s", macAddress);
7574 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007575 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7577 "Invalid MAC address or All hex inputs are not read (%d)", v);
7578 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007579 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007580
7581 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7582 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7583 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7584 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7585 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7586 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007587
7588 /* point to the next argument */
7589 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7590 /*no argument after the command*/
7591 if (NULL == inPtr) return -EINVAL;
7592
7593 /*removing empty spaces*/
7594 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7595
7596 /*no argument followed by spaces*/
7597 if ('\0' == *inPtr)
7598 {
7599 return -EINVAL;
7600 }
7601
7602 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007603 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007604 if (1 != v) return -EINVAL;
7605
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007606 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307607 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307608 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007609
7610 *pChannel = tempInt;
7611
7612 /* point to the next argument */
7613 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7614 /*no argument after the command*/
7615 if (NULL == inPtr) return -EINVAL;
7616 /*removing empty spaces*/
7617 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7618
7619 /*no argument followed by spaces*/
7620 if ('\0' == *inPtr)
7621 {
7622 return -EINVAL;
7623 }
7624
7625 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007626 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007627 if (1 != v) return -EINVAL;
7628
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007629 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007630 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007631
7632 *pDwellTime = tempInt;
7633
7634 /* point to the next argument */
7635 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7636 /*no argument after the command*/
7637 if (NULL == inPtr) return -EINVAL;
7638 /*removing empty spaces*/
7639 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7640
7641 /*no argument followed by spaces*/
7642 if ('\0' == *inPtr)
7643 {
7644 return -EINVAL;
7645 }
7646
7647 /* find the length of data */
7648 dataEnd = inPtr;
7649 while(('\0' != *dataEnd) )
7650 {
7651 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007652 }
Kiet Lambe150c22013-11-21 16:30:32 +05307653 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007654 if ( *pBufLen <= 0) return -EINVAL;
7655
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007656 /* Allocate the number of bytes based on the number of input characters
7657 whether it is even or odd.
7658 if the number of input characters are even, then we need N/2 byte.
7659 if the number of input characters are odd, then we need do (N+1)/2 to
7660 compensate rounding off.
7661 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7662 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7663 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007664 if (NULL == *pBuf)
7665 {
7666 hddLog(VOS_TRACE_LEVEL_FATAL,
7667 "%s: vos_mem_alloc failed ", __func__);
7668 return -EINVAL;
7669 }
7670
7671 /* the buffer received from the upper layer is character buffer,
7672 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7673 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7674 and f0 in 3rd location */
7675 for (i = 0, j = 0; j < *pBufLen; j += 2)
7676 {
Kiet Lambe150c22013-11-21 16:30:32 +05307677 if( j+1 == *pBufLen)
7678 {
7679 tempByte = hdd_parse_hex(inPtr[j]);
7680 }
7681 else
7682 {
7683 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7684 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007685 (*pBuf)[i++] = tempByte;
7686 }
7687 *pBufLen = i;
7688 return VOS_STATUS_SUCCESS;
7689}
7690
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007691/**---------------------------------------------------------------------------
7692
Srinivas Girigowdade697412013-02-14 16:31:48 -08007693 \brief hdd_parse_channellist() - HDD Parse channel list
7694
7695 This function parses the channel list passed in the format
7696 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007697 if the Number of channels (N) does not match with the actual number of channels passed
7698 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7699 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7700 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7701 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007702
7703 \param - pValue Pointer to input channel list
7704 \param - ChannelList Pointer to local output array to record channel list
7705 \param - pNumChannels Pointer to number of roam scan channels
7706
7707 \return - 0 for success non-zero for failure
7708
7709 --------------------------------------------------------------------------*/
7710VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7711{
7712 tANI_U8 *inPtr = pValue;
7713 int tempInt;
7714 int j = 0;
7715 int v = 0;
7716 char buf[32];
7717
7718 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7719 /*no argument after the command*/
7720 if (NULL == inPtr)
7721 {
7722 return -EINVAL;
7723 }
7724
7725 /*no space after the command*/
7726 else if (SPACE_ASCII_VALUE != *inPtr)
7727 {
7728 return -EINVAL;
7729 }
7730
7731 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007732 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007733
7734 /*no argument followed by spaces*/
7735 if ('\0' == *inPtr)
7736 {
7737 return -EINVAL;
7738 }
7739
7740 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007741 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007742 if (1 != v) return -EINVAL;
7743
Srinivas Girigowdade697412013-02-14 16:31:48 -08007744 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007745 if ((v < 0) ||
7746 (tempInt <= 0) ||
7747 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7748 {
7749 return -EINVAL;
7750 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007751
7752 *pNumChannels = tempInt;
7753
7754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7755 "Number of channels are: %d", *pNumChannels);
7756
7757 for (j = 0; j < (*pNumChannels); j++)
7758 {
7759 /*inPtr pointing to the beginning of first space after number of channels*/
7760 inPtr = strpbrk( inPtr, " " );
7761 /*no channel list after the number of channels argument*/
7762 if (NULL == inPtr)
7763 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007764 if (0 != j)
7765 {
7766 *pNumChannels = j;
7767 return VOS_STATUS_SUCCESS;
7768 }
7769 else
7770 {
7771 return -EINVAL;
7772 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007773 }
7774
7775 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007776 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007777
7778 /*no channel list after the number of channels argument and spaces*/
7779 if ( '\0' == *inPtr )
7780 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007781 if (0 != j)
7782 {
7783 *pNumChannels = j;
7784 return VOS_STATUS_SUCCESS;
7785 }
7786 else
7787 {
7788 return -EINVAL;
7789 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007790 }
7791
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007792 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007793 if (1 != v) return -EINVAL;
7794
Srinivas Girigowdade697412013-02-14 16:31:48 -08007795 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007796 if ((v < 0) ||
7797 (tempInt <= 0) ||
7798 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7799 {
7800 return -EINVAL;
7801 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007802 pChannelList[j] = tempInt;
7803
7804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7805 "Channel %d added to preferred channel list",
7806 pChannelList[j] );
7807 }
7808
Srinivas Girigowdade697412013-02-14 16:31:48 -08007809 return VOS_STATUS_SUCCESS;
7810}
7811
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007812
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307813/**
7814 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7815 * This function parses the reasoc command data passed in the format
7816 * REASSOC<space><bssid><space><channel>
7817 *
7818 * @pValue: Pointer to input data (its a NUL terminated string)
7819 * @pTargetApBssid: Pointer to target Ap bssid
7820 * @pChannel: Pointer to the Target AP channel
7821 *
7822 * Return: 0 for success non-zero for failure
7823 */
7824static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7825 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007826{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307827 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007828 int tempInt;
7829 int v = 0;
7830 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007831 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007832 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007833
7834 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7835 /*no argument after the command*/
7836 if (NULL == inPtr)
7837 {
7838 return -EINVAL;
7839 }
7840
7841 /*no space after the command*/
7842 else if (SPACE_ASCII_VALUE != *inPtr)
7843 {
7844 return -EINVAL;
7845 }
7846
7847 /*removing empty spaces*/
7848 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7849
7850 /*no argument followed by spaces*/
7851 if ('\0' == *inPtr)
7852 {
7853 return -EINVAL;
7854 }
7855
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007856 v = sscanf(inPtr, "%17s", macAddress);
7857 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007858 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7860 "Invalid MAC address or All hex inputs are not read (%d)", v);
7861 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007862 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007863
7864 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7865 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7866 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7867 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7868 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7869 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007870
7871 /* point to the next argument */
7872 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7873 /*no argument after the command*/
7874 if (NULL == inPtr) return -EINVAL;
7875
7876 /*removing empty spaces*/
7877 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7878
7879 /*no argument followed by spaces*/
7880 if ('\0' == *inPtr)
7881 {
7882 return -EINVAL;
7883 }
7884
7885 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007886 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007887 if (1 != v) return -EINVAL;
7888
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007889 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007890 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307891 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007892 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7893 {
7894 return -EINVAL;
7895 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007896
7897 *pChannel = tempInt;
7898 return VOS_STATUS_SUCCESS;
7899}
7900
7901#endif
7902
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007903#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007904/**---------------------------------------------------------------------------
7905
7906 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7907
7908 This function parses the SETCCKM IE command
7909 SETCCKMIE<space><ie data>
7910
7911 \param - pValue Pointer to input data
7912 \param - pCckmIe Pointer to output cckm Ie
7913 \param - pCckmIeLen Pointer to output cckm ie length
7914
7915 \return - 0 for success non-zero for failure
7916
7917 --------------------------------------------------------------------------*/
7918VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7919 tANI_U8 *pCckmIeLen)
7920{
7921 tANI_U8 *inPtr = pValue;
7922 tANI_U8 *dataEnd;
7923 int j = 0;
7924 int i = 0;
7925 tANI_U8 tempByte = 0;
7926
7927 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7928 /*no argument after the command*/
7929 if (NULL == inPtr)
7930 {
7931 return -EINVAL;
7932 }
7933
7934 /*no space after the command*/
7935 else if (SPACE_ASCII_VALUE != *inPtr)
7936 {
7937 return -EINVAL;
7938 }
7939
7940 /*removing empty spaces*/
7941 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7942
7943 /*no argument followed by spaces*/
7944 if ('\0' == *inPtr)
7945 {
7946 return -EINVAL;
7947 }
7948
7949 /* find the length of data */
7950 dataEnd = inPtr;
7951 while(('\0' != *dataEnd) )
7952 {
7953 dataEnd++;
7954 ++(*pCckmIeLen);
7955 }
7956 if ( *pCckmIeLen <= 0) return -EINVAL;
7957
7958 /* Allocate the number of bytes based on the number of input characters
7959 whether it is even or odd.
7960 if the number of input characters are even, then we need N/2 byte.
7961 if the number of input characters are odd, then we need do (N+1)/2 to
7962 compensate rounding off.
7963 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7964 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7965 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7966 if (NULL == *pCckmIe)
7967 {
7968 hddLog(VOS_TRACE_LEVEL_FATAL,
7969 "%s: vos_mem_alloc failed ", __func__);
7970 return -EINVAL;
7971 }
7972 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7973 /* the buffer received from the upper layer is character buffer,
7974 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7975 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7976 and f0 in 3rd location */
7977 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7978 {
7979 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7980 (*pCckmIe)[i++] = tempByte;
7981 }
7982 *pCckmIeLen = i;
7983
7984 return VOS_STATUS_SUCCESS;
7985}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007986#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007987
Jeff Johnson295189b2012-06-20 16:38:30 -07007988/**---------------------------------------------------------------------------
7989
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007990 \brief hdd_is_valid_mac_address() - Validate MAC address
7991
7992 This function validates whether the given MAC address is valid or not
7993 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7994 where X is the hexa decimal digit character and separated by ':'
7995 This algorithm works even if MAC address is not separated by ':'
7996
7997 This code checks given input string mac contains exactly 12 hexadecimal digits.
7998 and a separator colon : appears in the input string only after
7999 an even number of hex digits.
8000
8001 \param - pMacAddr pointer to the input MAC address
8002 \return - 1 for valid and 0 for invalid
8003
8004 --------------------------------------------------------------------------*/
8005
8006v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
8007{
8008 int xdigit = 0;
8009 int separator = 0;
8010 while (*pMacAddr)
8011 {
8012 if (isxdigit(*pMacAddr))
8013 {
8014 xdigit++;
8015 }
8016 else if (':' == *pMacAddr)
8017 {
8018 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8019 break;
8020
8021 ++separator;
8022 }
8023 else
8024 {
8025 separator = -1;
8026 /* Invalid MAC found */
8027 return 0;
8028 }
8029 ++pMacAddr;
8030 }
8031 return (xdigit == 12 && (separator == 5 || separator == 0));
8032}
8033
8034/**---------------------------------------------------------------------------
8035
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308036 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008037
8038 \param - dev Pointer to net_device structure
8039
8040 \return - 0 for success non-zero for failure
8041
8042 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308043int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008044{
8045 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8046 hdd_context_t *pHddCtx;
8047 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8048 VOS_STATUS status;
8049 v_BOOL_t in_standby = TRUE;
8050
8051 if (NULL == pAdapter)
8052 {
8053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308054 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 return -ENODEV;
8056 }
8057
8058 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308059 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8060 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 if (NULL == pHddCtx)
8062 {
8063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008064 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 return -ENODEV;
8066 }
8067
8068 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8069 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8070 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008071 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8072 {
8073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308074 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008075 in_standby = FALSE;
8076 break;
8077 }
8078 else
8079 {
8080 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8081 pAdapterNode = pNext;
8082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 }
8084
8085 if (TRUE == in_standby)
8086 {
8087 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8088 {
8089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8090 "wlan out of power save", __func__);
8091 return -EINVAL;
8092 }
8093 }
8094
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008095 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8097 {
8098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308101 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 netif_tx_start_all_queues(dev);
8103 }
8104
8105 return 0;
8106}
8107
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308108/**---------------------------------------------------------------------------
8109
8110 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8111
8112 This is called in response to ifconfig up
8113
8114 \param - dev Pointer to net_device structure
8115
8116 \return - 0 for success non-zero for failure
8117
8118 --------------------------------------------------------------------------*/
8119int hdd_open(struct net_device *dev)
8120{
8121 int ret;
8122
8123 vos_ssr_protect(__func__);
8124 ret = __hdd_open(dev);
8125 vos_ssr_unprotect(__func__);
8126
8127 return ret;
8128}
8129
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308130int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008131{
8132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308133 hdd_adapter_t *sta_adapter;
8134 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008135
8136 if(pAdapter == NULL) {
8137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008138 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008139 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 }
8141
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308142 if (vos_get_concurrency_mode() != VOS_STA_MON)
8143 return 0;
8144
8145 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8146 if (wlan_hdd_validate_context(hdd_ctx))
8147 return -EINVAL;
8148
8149 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8150 if (!sta_adapter) {
8151 hddLog(LOGE, FL("No valid STA interface"));
8152 return -EINVAL;
8153 }
8154
8155 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8156 hddLog(LOGE, FL("STA Interface is not OPENED"));
8157 return -EINVAL;
8158 }
8159
8160 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8161
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 return 0;
8163}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308164
8165int hdd_mon_open (struct net_device *dev)
8166{
8167 int ret;
8168
8169 vos_ssr_protect(__func__);
8170 ret = __hdd_mon_open(dev);
8171 vos_ssr_unprotect(__func__);
8172
8173 return ret;
8174}
8175
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308176int __hdd_mon_stop (struct net_device *dev)
8177{
8178 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8179 hdd_context_t *hdd_ctx;
8180
8181 if (vos_get_concurrency_mode() != VOS_STA_MON)
8182 return 0;
8183
8184 if(!mon_adapter) {
8185 hddLog(LOGE, FL("HDD adapter is Null"));
8186 return -EINVAL;
8187 }
8188
8189 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8190 if (wlan_hdd_validate_context(hdd_ctx))
8191 return -EINVAL;
8192
8193 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8194 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8195 return -ENODEV;
8196 }
8197
8198 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8199 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8200
8201 return 0;
8202}
8203
Katya Nigame7b69a82015-04-28 15:24:06 +05308204int hdd_mon_stop(struct net_device *dev)
8205{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308206 int ret;
8207
8208 vos_ssr_protect(__func__);
8209 ret = __hdd_mon_stop(dev);
8210 vos_ssr_unprotect(__func__);
8211
8212 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308213}
8214
Jeff Johnson295189b2012-06-20 16:38:30 -07008215/**---------------------------------------------------------------------------
8216
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308217 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008218
8219 \param - dev Pointer to net_device structure
8220
8221 \return - 0 for success non-zero for failure
8222
8223 --------------------------------------------------------------------------*/
8224
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308225int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008226{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308227 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8229 hdd_context_t *pHddCtx;
8230 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8231 VOS_STATUS status;
8232 v_BOOL_t enter_standby = TRUE;
8233
8234 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 if (NULL == pAdapter)
8236 {
8237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308238 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 return -ENODEV;
8240 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308241 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308242 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308243
8244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8245 ret = wlan_hdd_validate_context(pHddCtx);
8246 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308248 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 }
8250
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308251 /* Nothing to be done if the interface is not opened */
8252 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8253 {
8254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8255 "%s: NETDEV Interface is not OPENED", __func__);
8256 return -ENODEV;
8257 }
8258
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308259 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308260 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308261 * In STA + Monitor mode concurrency, no point in running
8262 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308263 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308264 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308265 }
8266
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308267 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008268 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308270
8271 /* Disable TX on the interface, after this hard_start_xmit() will not
8272 * be called on that interface
8273 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308276
8277 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 netif_carrier_off(pAdapter->dev);
8279
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308280 /* The interface is marked as down for outside world (aka kernel)
8281 * But the driver is pretty much alive inside. The driver needs to
8282 * tear down the existing connection on the netdev (session)
8283 * cleanup the data pipes and wait until the control plane is stabilized
8284 * for this interface. The call also needs to wait until the above
8285 * mentioned actions are completed before returning to the caller.
8286 * Notice that the hdd_stop_adapter is requested not to close the session
8287 * That is intentional to be able to scan if it is a STA/P2P interface
8288 */
8289 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308290#ifdef FEATURE_WLAN_TDLS
8291 mutex_lock(&pHddCtx->tdls_lock);
8292#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308293 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308294 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308295#ifdef FEATURE_WLAN_TDLS
8296 mutex_unlock(&pHddCtx->tdls_lock);
8297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 /* SoftAP ifaces should never go in power save mode
8299 making sure same here. */
8300 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008301 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 )
8303 {
8304 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8306 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 EXIT();
8308 return 0;
8309 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308310 /* Find if any iface is up. If any iface is up then can't put device to
8311 * sleep/power save mode
8312 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008313 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8314 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8315 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008316 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8317 {
8318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308319 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008320 enter_standby = FALSE;
8321 break;
8322 }
8323 else
8324 {
8325 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8326 pAdapterNode = pNext;
8327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 }
8329
8330 if (TRUE == enter_standby)
8331 {
8332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8333 "entering standby", __func__);
8334 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8335 {
8336 /*log and return success*/
8337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8338 "wlan in power save", __func__);
8339 }
8340 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308341
8342 /*
8343 * Upon wifi turn off, DUT has to flush the scan results so if
8344 * this is the last cli iface, flush the scan database.
8345 */
8346 if (!hdd_is_cli_iface_up(pHddCtx))
8347 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008348
8349 EXIT();
8350 return 0;
8351}
8352
8353/**---------------------------------------------------------------------------
8354
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308355 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008356
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308357 This is called in response to ifconfig down
8358
8359 \param - dev Pointer to net_device structure
8360
8361 \return - 0 for success non-zero for failure
8362-----------------------------------------------------------------------------*/
8363int hdd_stop (struct net_device *dev)
8364{
8365 int ret;
8366
8367 vos_ssr_protect(__func__);
8368 ret = __hdd_stop(dev);
8369 vos_ssr_unprotect(__func__);
8370
8371 return ret;
8372}
8373
8374/**---------------------------------------------------------------------------
8375
8376 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008377
8378 \param - dev Pointer to net_device structure
8379
8380 \return - void
8381
8382 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308383static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008384{
8385 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308386 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 ENTER();
8388
8389 do
8390 {
8391 if (NULL == pAdapter)
8392 {
8393 hddLog(VOS_TRACE_LEVEL_FATAL,
8394 "%s: NULL pAdapter", __func__);
8395 break;
8396 }
8397
8398 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8399 {
8400 hddLog(VOS_TRACE_LEVEL_FATAL,
8401 "%s: Invalid magic", __func__);
8402 break;
8403 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308404 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8405 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 {
8407 hddLog(VOS_TRACE_LEVEL_FATAL,
8408 "%s: NULL pHddCtx", __func__);
8409 break;
8410 }
8411
8412 if (dev != pAdapter->dev)
8413 {
8414 hddLog(VOS_TRACE_LEVEL_FATAL,
8415 "%s: Invalid device reference", __func__);
8416 /* we haven't validated all cases so let this go for now */
8417 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308418#ifdef FEATURE_WLAN_TDLS
8419 mutex_lock(&pHddCtx->tdls_lock);
8420#endif
c_hpothu002231a2015-02-05 14:58:51 +05308421 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308422#ifdef FEATURE_WLAN_TDLS
8423 mutex_unlock(&pHddCtx->tdls_lock);
8424#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008425
8426 /* after uninit our adapter structure will no longer be valid */
8427 pAdapter->dev = NULL;
8428 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308429 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 } while (0);
8431
8432 EXIT();
8433}
8434
8435/**---------------------------------------------------------------------------
8436
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308437 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8438
8439 This is called during the netdev unregister to uninitialize all data
8440associated with the device
8441
8442 \param - dev Pointer to net_device structure
8443
8444 \return - void
8445
8446 --------------------------------------------------------------------------*/
8447static void hdd_uninit (struct net_device *dev)
8448{
8449 vos_ssr_protect(__func__);
8450 __hdd_uninit(dev);
8451 vos_ssr_unprotect(__func__);
8452}
8453
8454/**---------------------------------------------------------------------------
8455
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 \brief hdd_release_firmware() -
8457
8458 This function calls the release firmware API to free the firmware buffer.
8459
8460 \param - pFileName Pointer to the File Name.
8461 pCtx - Pointer to the adapter .
8462
8463
8464 \return - 0 for success, non zero for failure
8465
8466 --------------------------------------------------------------------------*/
8467
8468VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8469{
8470 VOS_STATUS status = VOS_STATUS_SUCCESS;
8471 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8472 ENTER();
8473
8474
8475 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8476
8477 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8478
8479 if(pHddCtx->fw) {
8480 release_firmware(pHddCtx->fw);
8481 pHddCtx->fw = NULL;
8482 }
8483 else
8484 status = VOS_STATUS_E_FAILURE;
8485 }
8486 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8487 if(pHddCtx->nv) {
8488 release_firmware(pHddCtx->nv);
8489 pHddCtx->nv = NULL;
8490 }
8491 else
8492 status = VOS_STATUS_E_FAILURE;
8493
8494 }
8495
8496 EXIT();
8497 return status;
8498}
8499
8500/**---------------------------------------------------------------------------
8501
8502 \brief hdd_request_firmware() -
8503
8504 This function reads the firmware file using the request firmware
8505 API and returns the the firmware data and the firmware file size.
8506
8507 \param - pfileName - Pointer to the file name.
8508 - pCtx - Pointer to the adapter .
8509 - ppfw_data - Pointer to the pointer of the firmware data.
8510 - pSize - Pointer to the file size.
8511
8512 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8513
8514 --------------------------------------------------------------------------*/
8515
8516
8517VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8518{
8519 int status;
8520 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8521 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8522 ENTER();
8523
8524 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8525
8526 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8527
8528 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8529 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8530 __func__, pfileName);
8531 retval = VOS_STATUS_E_FAILURE;
8532 }
8533
8534 else {
8535 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8536 *pSize = pHddCtx->fw->size;
8537 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8538 __func__, *pSize);
8539 }
8540 }
8541 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8542
8543 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8544
8545 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8546 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8547 __func__, pfileName);
8548 retval = VOS_STATUS_E_FAILURE;
8549 }
8550
8551 else {
8552 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8553 *pSize = pHddCtx->nv->size;
8554 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8555 __func__, *pSize);
8556 }
8557 }
8558
8559 EXIT();
8560 return retval;
8561}
8562/**---------------------------------------------------------------------------
8563 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8564
8565 This is the function invoked by SME to inform the result of a full power
8566 request issued by HDD
8567
8568 \param - callbackcontext - Pointer to cookie
8569 status - result of request
8570
8571 \return - None
8572
8573--------------------------------------------------------------------------*/
8574void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8575{
8576 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8577
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008578 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 if(&pHddCtx->full_pwr_comp_var)
8580 {
8581 complete(&pHddCtx->full_pwr_comp_var);
8582 }
8583}
8584
Abhishek Singh00b71972016-01-07 10:51:04 +05308585#ifdef WLAN_FEATURE_RMC
8586static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8587{
8588 int payload_len;
8589 struct sk_buff *skb;
8590 struct nlmsghdr *nlh;
8591 v_U8_t *data;
8592
8593 payload_len = ETH_ALEN;
8594
8595 if (0 == cesium_pid)
8596 {
8597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8598 __func__);
8599 return;
8600 }
8601
8602 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8603 {
8604 hddLog(VOS_TRACE_LEVEL_ERROR,
8605 "%s: nlmsg_new() failed for msg size[%d]",
8606 __func__, NLMSG_SPACE(payload_len));
8607 return;
8608 }
8609
8610 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8611
8612 if (NULL == nlh)
8613 {
8614 hddLog(VOS_TRACE_LEVEL_ERROR,
8615 "%s: nlmsg_put() failed for msg size[%d]",
8616 __func__, NLMSG_SPACE(payload_len));
8617
8618 kfree_skb(skb);
8619 return;
8620 }
8621
8622 data = nlmsg_data(nlh);
8623 memcpy(data, MacAddr, ETH_ALEN);
8624
8625 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8626 {
8627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8628 __func__, NLMSG_SPACE(payload_len));
8629 }
8630
8631 return;
8632}
8633
8634/**---------------------------------------------------------------------------
8635 \brief hdd_ParseuserParams - return a pointer to the next argument
8636
8637 \return - status
8638
8639--------------------------------------------------------------------------*/
8640static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8641{
8642 tANI_U8 *pVal;
8643
8644 pVal = strchr(pValue, ' ');
8645
8646 if (NULL == pVal)
8647 {
8648 /* no argument remains */
8649 return -EINVAL;
8650 }
8651 else if (SPACE_ASCII_VALUE != *pVal)
8652 {
8653 /* no space after the current argument */
8654 return -EINVAL;
8655 }
8656
8657 pVal++;
8658
8659 /* remove empty spaces */
8660 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8661 {
8662 pVal++;
8663 }
8664
8665 /* no argument followed by spaces */
8666 if ('\0' == *pVal)
8667 {
8668 return -EINVAL;
8669 }
8670
8671 *ppArg = pVal;
8672
8673 return 0;
8674}
8675
8676/**----------------------------------------------------------------------------
8677 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8678
8679 \return - status
8680
8681------------------------------------------------------------------------------*/
8682static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8683 tANI_U8 *tx_fail_count,
8684 tANI_U16 *pid)
8685{
8686 tANI_U8 *param = NULL;
8687 int ret;
8688
8689 ret = hdd_ParseUserParams(pValue, &param);
8690
8691 if (0 == ret && NULL != param)
8692 {
8693 if (1 != sscanf(param, "%hhu", tx_fail_count))
8694 {
8695 ret = -EINVAL;
8696 goto done;
8697 }
8698 }
8699 else
8700 {
8701 goto done;
8702 }
8703
8704 if (0 == *tx_fail_count)
8705 {
8706 *pid = 0;
8707 goto done;
8708 }
8709
8710 pValue = param;
8711 pValue++;
8712
8713 ret = hdd_ParseUserParams(pValue, &param);
8714
8715 if (0 == ret)
8716 {
8717 if (1 != sscanf(param, "%hu", pid))
8718 {
8719 ret = -EINVAL;
8720 goto done;
8721 }
8722 }
8723 else
8724 {
8725 goto done;
8726 }
8727
8728done:
8729 return ret;
8730}
8731
8732static int hdd_open_cesium_nl_sock()
8733{
8734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8735 struct netlink_kernel_cfg cfg = {
8736 .groups = WLAN_NLINK_MCAST_GRP_ID,
8737 .input = NULL
8738 };
8739#endif
8740 int ret = 0;
8741
8742#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8743 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8744#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8745 THIS_MODULE,
8746#endif
8747 &cfg);
8748#else
8749 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8750 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8751#endif
8752
8753 if (cesium_nl_srv_sock == NULL)
8754 {
8755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8756 "NLINK: cesium netlink_kernel_create failed");
8757 ret = -ECONNREFUSED;
8758 }
8759
8760 return ret;
8761}
8762
8763static void hdd_close_cesium_nl_sock()
8764{
8765 if (NULL != cesium_nl_srv_sock)
8766 {
8767 netlink_kernel_release(cesium_nl_srv_sock);
8768 cesium_nl_srv_sock = NULL;
8769 }
8770}
8771#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008772/**---------------------------------------------------------------------------
8773
8774 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8775
8776 This is the function invoked by SME to inform the result of BMPS
8777 request issued by HDD
8778
8779 \param - callbackcontext - Pointer to cookie
8780 status - result of request
8781
8782 \return - None
8783
8784--------------------------------------------------------------------------*/
8785void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8786{
8787
8788 struct completion *completion_var = (struct completion*) callbackContext;
8789
Arif Hussain6d2a3322013-11-17 19:50:10 -08008790 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008791 if(completion_var != NULL)
8792 {
8793 complete(completion_var);
8794 }
8795}
8796
8797/**---------------------------------------------------------------------------
8798
8799 \brief hdd_get_cfg_file_size() -
8800
8801 This function reads the configuration file using the request firmware
8802 API and returns the configuration file size.
8803
8804 \param - pCtx - Pointer to the adapter .
8805 - pFileName - Pointer to the file name.
8806 - pBufSize - Pointer to the buffer size.
8807
8808 \return - 0 for success, non zero for failure
8809
8810 --------------------------------------------------------------------------*/
8811
8812VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8813{
8814 int status;
8815 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8816
8817 ENTER();
8818
8819 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8820
8821 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8822 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8823 status = VOS_STATUS_E_FAILURE;
8824 }
8825 else {
8826 *pBufSize = pHddCtx->fw->size;
8827 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8828 release_firmware(pHddCtx->fw);
8829 pHddCtx->fw = NULL;
8830 }
8831
8832 EXIT();
8833 return VOS_STATUS_SUCCESS;
8834}
8835
8836/**---------------------------------------------------------------------------
8837
8838 \brief hdd_read_cfg_file() -
8839
8840 This function reads the configuration file using the request firmware
8841 API and returns the cfg data and the buffer size of the configuration file.
8842
8843 \param - pCtx - Pointer to the adapter .
8844 - pFileName - Pointer to the file name.
8845 - pBuffer - Pointer to the data buffer.
8846 - pBufSize - Pointer to the buffer size.
8847
8848 \return - 0 for success, non zero for failure
8849
8850 --------------------------------------------------------------------------*/
8851
8852VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8853 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8854{
8855 int status;
8856 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8857
8858 ENTER();
8859
8860 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8861
8862 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8864 return VOS_STATUS_E_FAILURE;
8865 }
8866 else {
8867 if(*pBufSize != pHddCtx->fw->size) {
8868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8869 "file size", __func__);
8870 release_firmware(pHddCtx->fw);
8871 pHddCtx->fw = NULL;
8872 return VOS_STATUS_E_FAILURE;
8873 }
8874 else {
8875 if(pBuffer) {
8876 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8877 }
8878 release_firmware(pHddCtx->fw);
8879 pHddCtx->fw = NULL;
8880 }
8881 }
8882
8883 EXIT();
8884
8885 return VOS_STATUS_SUCCESS;
8886}
8887
8888/**---------------------------------------------------------------------------
8889
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308890 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008891
8892 This function sets the user specified mac address using
8893 the command ifconfig wlanX hw ether <mac adress>.
8894
8895 \param - dev - Pointer to the net device.
8896 - addr - Pointer to the sockaddr.
8897 \return - 0 for success, non zero for failure
8898
8899 --------------------------------------------------------------------------*/
8900
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308901static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008902{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308903 hdd_adapter_t *pAdapter;
8904 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 struct sockaddr *psta_mac_addr = addr;
8906 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308907 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008908
8909 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308910 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8911 if (NULL == pAdapter)
8912 {
8913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8914 "%s: Adapter is NULL",__func__);
8915 return -EINVAL;
8916 }
8917 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8918 ret = wlan_hdd_validate_context(pHddCtx);
8919 if (0 != ret)
8920 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308921 return ret;
8922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
8924 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8926
8927 EXIT();
8928 return halStatus;
8929}
8930
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308931/**---------------------------------------------------------------------------
8932
8933 \brief hdd_set_mac_address() -
8934
8935 Wrapper function to protect __hdd_set_mac_address() function from ssr
8936
8937 \param - dev - Pointer to the net device.
8938 - addr - Pointer to the sockaddr.
8939 \return - 0 for success, non zero for failure
8940
8941 --------------------------------------------------------------------------*/
8942static int hdd_set_mac_address(struct net_device *dev, void *addr)
8943{
8944 int ret;
8945
8946 vos_ssr_protect(__func__);
8947 ret = __hdd_set_mac_address(dev, addr);
8948 vos_ssr_unprotect(__func__);
8949
8950 return ret;
8951}
8952
Jeff Johnson295189b2012-06-20 16:38:30 -07008953tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8954{
8955 int i;
8956 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8957 {
Abhishek Singheb183782014-02-06 13:37:21 +05308958 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 break;
8960 }
8961
8962 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8963 return NULL;
8964
8965 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8966 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8967}
8968
8969void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8970{
8971 int i;
8972 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8973 {
8974 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8975 {
8976 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8977 break;
8978 }
8979 }
8980 return;
8981}
8982
8983#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8984 static struct net_device_ops wlan_drv_ops = {
8985 .ndo_open = hdd_open,
8986 .ndo_stop = hdd_stop,
8987 .ndo_uninit = hdd_uninit,
8988 .ndo_start_xmit = hdd_hard_start_xmit,
8989 .ndo_tx_timeout = hdd_tx_timeout,
8990 .ndo_get_stats = hdd_stats,
8991 .ndo_do_ioctl = hdd_ioctl,
8992 .ndo_set_mac_address = hdd_set_mac_address,
8993 .ndo_select_queue = hdd_select_queue,
8994#ifdef WLAN_FEATURE_PACKET_FILTERING
8995#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8996 .ndo_set_rx_mode = hdd_set_multicast_list,
8997#else
8998 .ndo_set_multicast_list = hdd_set_multicast_list,
8999#endif //LINUX_VERSION_CODE
9000#endif
9001 };
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 static struct net_device_ops wlan_mon_drv_ops = {
9003 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05309004 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 .ndo_uninit = hdd_uninit,
9006 .ndo_start_xmit = hdd_mon_hard_start_xmit,
9007 .ndo_tx_timeout = hdd_tx_timeout,
9008 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05309009 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 .ndo_set_mac_address = hdd_set_mac_address,
9011 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309012
Jeff Johnson295189b2012-06-20 16:38:30 -07009013#endif
9014
9015void hdd_set_station_ops( struct net_device *pWlanDev )
9016{
9017#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 pWlanDev->netdev_ops = &wlan_drv_ops;
9019#else
9020 pWlanDev->open = hdd_open;
9021 pWlanDev->stop = hdd_stop;
9022 pWlanDev->uninit = hdd_uninit;
9023 pWlanDev->hard_start_xmit = NULL;
9024 pWlanDev->tx_timeout = hdd_tx_timeout;
9025 pWlanDev->get_stats = hdd_stats;
9026 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009027 pWlanDev->set_mac_address = hdd_set_mac_address;
9028#endif
9029}
9030
Katya Nigam1fd24402015-02-16 14:52:19 +05309031void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9032{
9033 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9034 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9035 #else
9036 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9037 #endif
9038}
9039
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009040static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009041{
9042 struct net_device *pWlanDev = NULL;
9043 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 /*
9045 * cfg80211 initialization and registration....
9046 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309047 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9049 NET_NAME_UNKNOWN,
9050#endif
9051 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 if(pWlanDev != NULL)
9053 {
9054
9055 //Save the pointer to the net_device in the HDD adapter
9056 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9059
9060 pAdapter->dev = pWlanDev;
9061 pAdapter->pHddCtx = pHddCtx;
9062 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309063 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009064
Rajeev79dbe4c2013-10-05 11:03:42 +05309065#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309066 pAdapter->pBatchScanRsp = NULL;
9067 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009068 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009069 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309070 mutex_init(&pAdapter->hdd_batch_scan_lock);
9071#endif
9072
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 pAdapter->isLinkUpSvcNeeded = FALSE;
9074 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9075 //Init the net_device structure
9076 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9077
9078 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9079 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9080 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309081
9082 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009083
9084 hdd_set_station_ops( pAdapter->dev );
9085
9086 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009087 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9088 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9089 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 /* set pWlanDev's parent to underlying device */
9091 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009092
9093 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009094 }
9095
9096 return pAdapter;
9097}
9098
9099VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9100{
9101 struct net_device *pWlanDev = pAdapter->dev;
9102 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9103 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9104 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9105
9106 if( rtnl_lock_held )
9107 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009108 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9110 {
9111 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9112 return VOS_STATUS_E_FAILURE;
9113 }
9114 }
9115 if (register_netdevice(pWlanDev))
9116 {
9117 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9118 return VOS_STATUS_E_FAILURE;
9119 }
9120 }
9121 else
9122 {
9123 if(register_netdev(pWlanDev))
9124 {
9125 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9126 return VOS_STATUS_E_FAILURE;
9127 }
9128 }
9129 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9130
9131 return VOS_STATUS_SUCCESS;
9132}
9133
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009134static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009135{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009136 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009137
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009138 if (NULL == pAdapter)
9139 {
9140 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9141 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009143
9144 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9145 {
9146 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9147 return eHAL_STATUS_NOT_INITIALIZED;
9148 }
9149
9150 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9151
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009152#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009153 /* need to make sure all of our scheduled work has completed.
9154 * This callback is called from MC thread context, so it is safe to
9155 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009156 *
9157 * Even though this is called from MC thread context, if there is a faulty
9158 * work item in the system, that can hang this call forever. So flushing
9159 * this global work queue is not safe; and now we make sure that
9160 * individual work queues are stopped correctly. But the cancel work queue
9161 * is a GPL only API, so the proprietary version of the driver would still
9162 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009163 */
9164 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009165#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009166
9167 /* We can be blocked while waiting for scheduled work to be
9168 * flushed, and the adapter structure can potentially be freed, in
9169 * which case the magic will have been reset. So make sure the
9170 * magic is still good, and hence the adapter structure is still
9171 * valid, before signaling completion */
9172 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9173 {
9174 complete(&pAdapter->session_close_comp_var);
9175 }
9176
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 return eHAL_STATUS_SUCCESS;
9178}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309179/**
9180 * hdd_close_tx_queues() - close tx queues
9181 * @hdd_ctx: hdd global context
9182 *
9183 * Return: None
9184 */
9185static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9186{
9187 VOS_STATUS status;
9188 hdd_adapter_t *adapter;
9189 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9190 /* Not validating hdd_ctx as it's already done by the caller */
9191 ENTER();
9192 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9193 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9194 adapter = adapter_node->pAdapter;
9195 if (adapter && adapter->dev) {
9196 netif_tx_disable (adapter->dev);
9197 netif_carrier_off(adapter->dev);
9198 }
9199 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9200 &next_adapter);
9201 adapter_node = next_adapter;
9202 }
9203 EXIT();
9204}
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
9206VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9207{
9208 struct net_device *pWlanDev = pAdapter->dev;
9209 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9210 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9211 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9212 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309213 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009214
Nirav Shah7e3c8132015-06-22 23:51:42 +05309215 spin_lock_init( &pAdapter->sta_hash_lock);
9216 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9217
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009219 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 //Open a SME session for future operation
9221 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009222 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9224 {
9225 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009226 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 halStatus, halStatus );
9228 status = VOS_STATUS_E_FAILURE;
9229 goto error_sme_open;
9230 }
9231
9232 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309233 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009234 &pAdapter->session_open_comp_var,
9235 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309236 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 {
9238 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309239 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 status = VOS_STATUS_E_FAILURE;
9241 goto error_sme_open;
9242 }
9243
9244 // Register wireless extensions
9245 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9246 {
9247 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009248 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 halStatus, halStatus );
9250 status = VOS_STATUS_E_FAILURE;
9251 goto error_register_wext;
9252 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309253
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309255 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9256 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9257 #else
9258 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9259 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009260
9261 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309262 hddLog(VOS_TRACE_LEVEL_INFO,
9263 "%s: Set HDD connState to eConnectionState_NotConnected",
9264 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9266
9267 //Set the default operation channel
9268 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9269
9270 /* Make the default Auth Type as OPEN*/
9271 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9272
9273 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9274 {
9275 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009276 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 status, status );
9278 goto error_init_txrx;
9279 }
9280
9281 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9282
9283 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9284 {
9285 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009286 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 status, status );
9288 goto error_wmm_init;
9289 }
9290
9291 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9292
9293 return VOS_STATUS_SUCCESS;
9294
9295error_wmm_init:
9296 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9297 hdd_deinit_tx_rx(pAdapter);
9298error_init_txrx:
9299 hdd_UnregisterWext(pWlanDev);
9300error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009301 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 {
9303 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009304 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309305 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009306 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309308 unsigned long rc;
9309
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309311 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009312 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009313 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309314 if (rc <= 0)
9315 hddLog(VOS_TRACE_LEVEL_ERROR,
9316 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 }
9318}
9319error_sme_open:
9320 return status;
9321}
9322
Jeff Johnson295189b2012-06-20 16:38:30 -07009323void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9324{
9325 hdd_cfg80211_state_t *cfgState;
9326
9327 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9328
9329 if( NULL != cfgState->buf )
9330 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309331 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9333 rc = wait_for_completion_interruptible_timeout(
9334 &pAdapter->tx_action_cnf_event,
9335 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309336 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9339 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9340 , __func__, rc);
9341
9342 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9343 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 }
9345 }
9346 return;
9347}
Jeff Johnson295189b2012-06-20 16:38:30 -07009348
c_hpothu002231a2015-02-05 14:58:51 +05309349void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009350{
9351 ENTER();
9352 switch ( pAdapter->device_mode )
9353 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309354 case WLAN_HDD_IBSS:
9355 {
9356 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9357 {
9358 hdd_ibss_deinit_tx_rx( pAdapter );
9359 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9360 }
9361 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 case WLAN_HDD_INFRA_STATION:
9363 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009364 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 {
9366 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9367 {
9368 hdd_deinit_tx_rx( pAdapter );
9369 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9370 }
9371
9372 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9373 {
9374 hdd_wmm_adapter_close( pAdapter );
9375 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9376 }
9377
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 break;
9380 }
9381
9382 case WLAN_HDD_SOFTAP:
9383 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309385
9386 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9387 {
9388 hdd_wmm_adapter_close( pAdapter );
9389 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9390 }
9391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009393
c_hpothu002231a2015-02-05 14:58:51 +05309394 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309395 /* set con_mode to STA only when no SAP concurrency mode */
9396 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9397 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 break;
9399 }
9400
9401 case WLAN_HDD_MONITOR:
9402 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9404 {
9405 hdd_deinit_tx_rx( pAdapter );
9406 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 break;
9409 }
9410
9411
9412 default:
9413 break;
9414 }
9415
9416 EXIT();
9417}
9418
9419void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9420{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009421 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309422
9423 ENTER();
9424 if (NULL == pAdapter)
9425 {
9426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9427 "%s: HDD adapter is Null", __func__);
9428 return;
9429 }
9430
9431 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009432
Rajeev79dbe4c2013-10-05 11:03:42 +05309433#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309434 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9435 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009436 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309437 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9438 )
9439 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009440 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309441 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009442 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9443 {
9444 hdd_deinit_batch_scan(pAdapter);
9445 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309446 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009447 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309448#endif
9449
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9451 if( rtnl_held )
9452 {
9453 unregister_netdevice(pWlanDev);
9454 }
9455 else
9456 {
9457 unregister_netdev(pWlanDev);
9458 }
9459 // note that the pAdapter is no longer valid at this point
9460 // since the memory has been reclaimed
9461 }
9462
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309463 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009464}
9465
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009466void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9467{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309468 VOS_STATUS status;
9469 hdd_adapter_t *pAdapter = NULL;
9470 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009471
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309472 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009473
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309474 /*loop through all adapters.*/
9475 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009476 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309477 pAdapter = pAdapterNode->pAdapter;
9478 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9479 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009480
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309481 { // we skip this registration for modes other than STA and P2P client modes.
9482 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9483 pAdapterNode = pNext;
9484 continue;
9485 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009486
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309487 //Apply Dynamic DTIM For P2P
9488 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9489 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9490 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9491 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9492 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9493 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9494 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9495 (eConnectionState_Associated ==
9496 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9497 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9498 {
9499 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009500
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309501 powerRequest.uIgnoreDTIM = 1;
9502 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9503
9504 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9505 {
9506 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9507 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9508 }
9509 else
9510 {
9511 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9512 }
9513
9514 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9515 * specified during Enter/Exit BMPS when LCD off*/
9516 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9517 NULL, eANI_BOOLEAN_FALSE);
9518 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9519 NULL, eANI_BOOLEAN_FALSE);
9520
9521 /* switch to the DTIM specified in cfg.ini */
9522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309523 "Switch to DTIM %d Listen interval %d",
9524 powerRequest.uDTIMPeriod,
9525 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309526 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9527 break;
9528
9529 }
9530
9531 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9532 pAdapterNode = pNext;
9533 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009534}
9535
9536void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9537{
9538 /*Switch back to DTIM 1*/
9539 tSirSetPowerParamsReq powerRequest = { 0 };
9540
9541 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9542 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009543 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009544
9545 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9546 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9547 NULL, eANI_BOOLEAN_FALSE);
9548 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9549 NULL, eANI_BOOLEAN_FALSE);
9550
9551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9552 "Switch to DTIM%d",powerRequest.uListenInterval);
9553 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9554
9555}
9556
Jeff Johnson295189b2012-06-20 16:38:30 -07009557VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9558{
9559 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309560 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9561 {
9562 hddLog( LOGE, FL("Wlan Unload in progress"));
9563 return VOS_STATUS_E_PERM;
9564 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309565
9566 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9567 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9568 return VOS_STATUS_SUCCESS;
9569 }
9570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9572 {
9573 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9574 }
9575
9576 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9577 {
9578 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9579 }
9580
9581 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9582 {
9583 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9584 }
9585
9586 return status;
9587}
9588
9589VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9590{
9591 hdd_adapter_t *pAdapter = NULL;
9592 eHalStatus halStatus;
9593 VOS_STATUS status = VOS_STATUS_E_INVAL;
9594 v_BOOL_t disableBmps = FALSE;
9595 v_BOOL_t disableImps = FALSE;
9596
9597 switch(session_type)
9598 {
9599 case WLAN_HDD_INFRA_STATION:
9600 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 case WLAN_HDD_P2P_CLIENT:
9602 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 //Exit BMPS -> Is Sta/P2P Client is already connected
9604 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9605 if((NULL != pAdapter)&&
9606 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9607 {
9608 disableBmps = TRUE;
9609 }
9610
9611 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9612 if((NULL != pAdapter)&&
9613 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9614 {
9615 disableBmps = TRUE;
9616 }
9617
9618 //Exit both Bmps and Imps incase of Go/SAP Mode
9619 if((WLAN_HDD_SOFTAP == session_type) ||
9620 (WLAN_HDD_P2P_GO == session_type))
9621 {
9622 disableBmps = TRUE;
9623 disableImps = TRUE;
9624 }
9625
9626 if(TRUE == disableImps)
9627 {
9628 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9629 {
9630 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9631 }
9632 }
9633
9634 if(TRUE == disableBmps)
9635 {
9636 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9637 {
9638 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9639
9640 if(eHAL_STATUS_SUCCESS != halStatus)
9641 {
9642 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009643 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 VOS_ASSERT(0);
9645 return status;
9646 }
9647 }
9648
9649 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9650 {
9651 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9652
9653 if(eHAL_STATUS_SUCCESS != halStatus)
9654 {
9655 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009656 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 VOS_ASSERT(0);
9658 return status;
9659 }
9660 }
9661 }
9662
9663 if((TRUE == disableBmps) ||
9664 (TRUE == disableImps))
9665 {
9666 /* Now, get the chip into Full Power now */
9667 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9668 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9669 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9670
9671 if(halStatus != eHAL_STATUS_SUCCESS)
9672 {
9673 if(halStatus == eHAL_STATUS_PMC_PENDING)
9674 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309675 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309677 ret = wait_for_completion_interruptible_timeout(
9678 &pHddCtx->full_pwr_comp_var,
9679 msecs_to_jiffies(1000));
9680 if (ret <= 0)
9681 {
9682 hddLog(VOS_TRACE_LEVEL_ERROR,
9683 "%s: wait on full_pwr_comp_var failed %ld",
9684 __func__, ret);
9685 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 }
9687 else
9688 {
9689 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009690 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 VOS_ASSERT(0);
9692 return status;
9693 }
9694 }
9695
9696 status = VOS_STATUS_SUCCESS;
9697 }
9698
9699 break;
9700 }
9701 return status;
9702}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309703
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309704void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309705{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309706 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309707
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309708 request = hdd_request_get(context);
9709 if (!request) {
9710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9711 return;
9712 }
9713
9714 hdd_request_complete(request);
9715 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309716}
9717
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309718
Katya Nigame7b69a82015-04-28 15:24:06 +05309719void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9720 {
9721 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309722
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309723 spin_lock_init(&pAdapter->sta_hash_lock);
9724 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9725
9726 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309727 pMonCtx->state = 0;
9728 pMonCtx->ChannelNo = 1;
9729 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309730 pMonCtx->crcCheckEnabled = 1;
9731 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9732 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309733 pMonCtx->numOfMacFilters = 0;
9734 }
9735
Jeff Johnson295189b2012-06-20 16:38:30 -07009736
9737hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009738 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 tANI_U8 rtnl_held )
9740{
9741 hdd_adapter_t *pAdapter = NULL;
9742 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9743 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9744 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309745 v_CONTEXT_t pVosContext = NULL;
9746
9747 /* No need to check for NULL, reaching this step
9748 * means vos context is initialized
9749 */
9750 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009751
Arif Hussain6d2a3322013-11-17 19:50:10 -08009752 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009753
Nirav Shah436658f2014-02-28 17:05:45 +05309754 if(macAddr == NULL)
9755 {
9756 /* Not received valid macAddr */
9757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9758 "%s:Unable to add virtual intf: Not able to get"
9759 "valid mac address",__func__);
9760 return NULL;
9761 }
9762
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 //Disable BMPS incase of Concurrency
9764 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9765
9766 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9767 {
9768 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309769 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 VOS_ASSERT(0);
9771 return NULL;
9772 }
9773
9774 switch(session_type)
9775 {
9776 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009778 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 {
9780 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9781
9782 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309783 {
9784 hddLog(VOS_TRACE_LEVEL_FATAL,
9785 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309789#ifdef FEATURE_WLAN_TDLS
9790 /* A Mutex Lock is introduced while changing/initializing the mode to
9791 * protect the concurrent access for the Adapters by TDLS module.
9792 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309793 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309794#endif
9795
Jeff Johnsone7245742012-09-05 17:12:55 -07009796 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9797 NL80211_IFTYPE_P2P_CLIENT:
9798 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309801#ifdef FEATURE_WLAN_TDLS
9802 mutex_unlock(&pHddCtx->tdls_lock);
9803#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309804
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309805 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309806 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 if( VOS_STATUS_SUCCESS != status )
9808 goto err_free_netdev;
9809
9810 status = hdd_register_interface( pAdapter, rtnl_held );
9811 if( VOS_STATUS_SUCCESS != status )
9812 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309813#ifdef FEATURE_WLAN_TDLS
9814 mutex_lock(&pHddCtx->tdls_lock);
9815#endif
c_hpothu002231a2015-02-05 14:58:51 +05309816 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309817#ifdef FEATURE_WLAN_TDLS
9818 mutex_unlock(&pHddCtx->tdls_lock);
9819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 goto err_free_netdev;
9821 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309822
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309823 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309824 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309825
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309826#ifdef WLAN_NS_OFFLOAD
9827 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309828 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309831 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009832 netif_tx_disable(pAdapter->dev);
9833 //netif_tx_disable(pWlanDev);
9834 netif_carrier_off(pAdapter->dev);
9835
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309836 if (WLAN_HDD_P2P_CLIENT == session_type ||
9837 WLAN_HDD_P2P_DEVICE == session_type)
9838 {
9839 /* Initialize the work queue to defer the
9840 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309841 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309842 hdd_p2p_roc_work_queue);
9843 }
9844
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 break;
9846 }
9847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 case WLAN_HDD_SOFTAP:
9850 {
9851 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9852 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309853 {
9854 hddLog(VOS_TRACE_LEVEL_FATAL,
9855 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309857 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009858
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9860 NL80211_IFTYPE_AP:
9861 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 pAdapter->device_mode = session_type;
9863
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309864 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309865 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 if( VOS_STATUS_SUCCESS != status )
9867 goto err_free_netdev;
9868
Nirav Shah7e3c8132015-06-22 23:51:42 +05309869 status = hdd_sta_id_hash_attach(pAdapter);
9870 if (VOS_STATUS_SUCCESS != status)
9871 {
9872 hddLog(VOS_TRACE_LEVEL_FATAL,
9873 FL("failed to attach hash for session %d"), session_type);
9874 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9875 goto err_free_netdev;
9876 }
9877
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 status = hdd_register_hostapd( pAdapter, rtnl_held );
9879 if( VOS_STATUS_SUCCESS != status )
9880 {
c_hpothu002231a2015-02-05 14:58:51 +05309881 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 goto err_free_netdev;
9883 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309884 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 netif_tx_disable(pAdapter->dev);
9886 netif_carrier_off(pAdapter->dev);
9887
9888 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309889
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309890 // Workqueue which gets scheduled in IPv4 notification callback.
9891 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9892 hdd_ipv4_notifier_work_queue);
9893
9894#ifdef WLAN_NS_OFFLOAD
9895 // Workqueue which gets scheduled in IPv6 notification callback.
9896 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9897 hdd_ipv6_notifier_work_queue);
9898#endif
9899
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309900 if (WLAN_HDD_P2P_GO == session_type)
9901 {
9902 /* Initialize the work queue to
9903 * defer the back to back RoC request */
9904 INIT_DELAYED_WORK(&pAdapter->roc_work,
9905 hdd_p2p_roc_work_queue);
9906 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309907
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 break;
9909 }
9910 case WLAN_HDD_MONITOR:
9911 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9913 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309914 {
9915 hddLog(VOS_TRACE_LEVEL_FATAL,
9916 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309918 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009919
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309920 pAdapter->device_mode = session_type;
9921 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9922
Katya Nigame7b69a82015-04-28 15:24:06 +05309923 // Register wireless extensions
9924 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9925 {
9926 hddLog(VOS_TRACE_LEVEL_FATAL,
9927 "hdd_register_wext() failed with status code %08d [x%08x]",
9928 status, status );
9929 status = VOS_STATUS_E_FAILURE;
9930 }
9931
Jeff Johnson295189b2012-06-20 16:38:30 -07009932#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9933 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9934#else
9935 pAdapter->dev->open = hdd_mon_open;
9936 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309937 pAdapter->dev->stop = hdd_mon_stop;
9938 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009939#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309940 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309941 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309943
9944 if (VOS_MONITOR_MODE != hdd_get_conparam())
9945 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309948 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309949 //Stop the Interface TX queue.
9950 netif_tx_disable(pAdapter->dev);
9951 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 }
9953 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 case WLAN_HDD_FTM:
9955 {
9956 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9957
9958 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309959 {
9960 hddLog(VOS_TRACE_LEVEL_FATAL,
9961 FL("failed to allocate adapter for session %d"), session_type);
9962 return NULL;
9963 }
9964
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9966 * message while loading driver in FTM mode. */
9967 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9968 pAdapter->device_mode = session_type;
9969 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309970
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309971 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309972 hdd_init_tx_rx( pAdapter );
9973
9974 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309975 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309976 netif_tx_disable(pAdapter->dev);
9977 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 }
9979 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 default:
9981 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309982 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9983 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 VOS_ASSERT(0);
9985 return NULL;
9986 }
9987 }
9988
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 if( VOS_STATUS_SUCCESS == status )
9990 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309991 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9993 if( NULL == pHddAdapterNode )
9994 {
9995 status = VOS_STATUS_E_NOMEM;
9996 }
9997 else
9998 {
9999 pHddAdapterNode->pAdapter = pAdapter;
10000 status = hdd_add_adapter_back ( pHddCtx,
10001 pHddAdapterNode );
10002 }
10003 }
10004
10005 if( VOS_STATUS_SUCCESS != status )
10006 {
10007 if( NULL != pAdapter )
10008 {
10009 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
10010 pAdapter = NULL;
10011 }
10012 if( NULL != pHddAdapterNode )
10013 {
10014 vos_mem_free( pHddAdapterNode );
10015 }
10016
10017 goto resume_bmps;
10018 }
10019
10020 if(VOS_STATUS_SUCCESS == status)
10021 {
10022 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010023 //Initialize the WoWL service
10024 if(!hdd_init_wowl(pAdapter))
10025 {
10026 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10027 goto err_free_netdev;
10028 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010029 //Initialize the TSF capture data
10030 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 return pAdapter;
10033
10034err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 wlan_hdd_release_intf_addr( pHddCtx,
10036 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010037 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010038
10039resume_bmps:
10040 //If bmps disabled enable it
10041 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10042 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010043 if (pHddCtx->hdd_wlan_suspended)
10044 {
10045 hdd_set_pwrparams(pHddCtx);
10046 }
10047 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 }
10049 return NULL;
10050}
10051
10052VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10053 tANI_U8 rtnl_held )
10054{
10055 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10056 VOS_STATUS status;
10057
10058 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10059 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010060 {
10061 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10062 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010064 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010065
10066 while ( pCurrent->pAdapter != pAdapter )
10067 {
10068 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10069 if( VOS_STATUS_SUCCESS != status )
10070 break;
10071
10072 pCurrent = pNext;
10073 }
10074 pAdapterNode = pCurrent;
10075 if( VOS_STATUS_SUCCESS == status )
10076 {
10077 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10078 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010079
10080#ifdef FEATURE_WLAN_TDLS
10081
10082 /* A Mutex Lock is introduced while changing/initializing the mode to
10083 * protect the concurrent access for the Adapters by TDLS module.
10084 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010085 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010086#endif
10087
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 hdd_remove_adapter( pHddCtx, pAdapterNode );
10089 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010090 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010091
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010092#ifdef FEATURE_WLAN_TDLS
10093 mutex_unlock(&pHddCtx->tdls_lock);
10094#endif
10095
Jeff Johnson295189b2012-06-20 16:38:30 -070010096
10097 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010098 if ((!vos_concurrent_open_sessions_running()) &&
10099 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10100 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010102 if (pHddCtx->hdd_wlan_suspended)
10103 {
10104 hdd_set_pwrparams(pHddCtx);
10105 }
10106 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 }
10108
10109 return VOS_STATUS_SUCCESS;
10110 }
10111
10112 return VOS_STATUS_E_FAILURE;
10113}
10114
10115VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10116{
10117 hdd_adapter_list_node_t *pHddAdapterNode;
10118 VOS_STATUS status;
10119
10120 ENTER();
10121
10122 do
10123 {
10124 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10125 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10126 {
10127 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10128 vos_mem_free( pHddAdapterNode );
10129 }
10130 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10131
10132 EXIT();
10133
10134 return VOS_STATUS_SUCCESS;
10135}
10136
10137void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10138{
10139 v_U8_t addIE[1] = {0};
10140
10141 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10142 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10143 eANI_BOOLEAN_FALSE) )
10144 {
10145 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010146 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 }
10148
10149 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10150 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10151 eANI_BOOLEAN_FALSE) )
10152 {
10153 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010154 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 }
10156
10157 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10158 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10159 eANI_BOOLEAN_FALSE) )
10160 {
10161 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010162 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 }
10164}
10165
Anurag Chouhan83026002016-12-13 22:46:21 +053010166VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10167{
10168#ifdef DHCP_SERVER_OFFLOAD
10169 vos_event_destroy(&adapter->dhcp_status.vos_event);
10170#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010171#ifdef MDNS_OFFLOAD
10172 vos_event_destroy(&adapter->mdns_status.vos_event);
10173#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010174 return VOS_STATUS_SUCCESS;
10175}
10176
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010177int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10178{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010179 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010180 hdd_mon_ctx_t *mon_ctx;
10181 void (*func_ptr)(void *context) = NULL;
10182 int ret = 0;
10183 void *cookie = NULL;
10184 struct hdd_request *request;
10185 static const struct hdd_request_params params = {
10186 .priv_size = 0,
10187 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10188 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010189
10190 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10191 if (!adapter) {
10192 hddLog(LOGE, FL("Invalid STA + MON mode"));
10193 return -EINVAL;
10194 }
10195
10196 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10197 if (!mon_ctx)
10198 return 0;
10199
10200 if (mon_ctx->state != MON_MODE_START)
10201 return 0;
10202
10203 mon_ctx->state = MON_MODE_STOP;
10204 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010205 func_ptr = hdd_mon_post_msg_cb;
10206 request = hdd_request_alloc(&params);
10207 if (!request) {
10208 hddLog(VOS_TRACE_LEVEL_ERROR,
10209 FL("Request allocation failure"));
10210 return -ENOMEM;
10211 }
10212 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010213 }
10214
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010215 /*
10216 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10217 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10218 * and so uninitialized cookie won't be accessed.
10219 */
10220 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010221 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010222 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010223 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010224 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010225 }
10226
10227 if (!wait)
10228 goto bmps_roaming;
10229
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010230 if (!ret)
10231 ret = hdd_request_wait_for_response(request);
10232 hdd_request_put(request);
10233 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010234 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010235 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010236 return -EINVAL;
10237 }
10238
10239bmps_roaming:
10240 hddLog(LOG1, FL("Enable BMPS"));
10241 hdd_enable_bmps_imps(hdd_ctx);
10242 hdd_restore_roaming(hdd_ctx);
10243
10244 return 0;
10245}
10246
10247bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10248{
10249 hdd_adapter_t *mon_adapter;
10250 hdd_mon_ctx_t *mon_ctx;
10251
10252 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10253 return false;
10254
10255 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10256 if (!mon_adapter) {
10257 hddLog(LOGE, FL("Invalid concurrency mode"));
10258 return false;
10259 }
10260
10261 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10262 if (mon_ctx->state == MON_MODE_START)
10263 return true;
10264
10265 return false;
10266}
10267
10268int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10269{
10270 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10271
10272 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10273 !wlan_hdd_check_monitor_state(hdd_ctx))
10274 return 0;
10275
10276 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10277 return -EINVAL;
10278
10279 return 0;
10280}
10281
10282void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10283{
10284 if (!hdd_ctx)
10285 return;
10286
10287 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10288 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10289 return;
10290 }
10291
10292 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10293
10294 hdd_ctx->roaming_ini_original =
10295 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10296
10297 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10298 CFG_LFR_FEATURE_ENABLED_MIN;
10299
10300 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10301 CFG_LFR_FEATURE_ENABLED_MIN);
10302}
10303
10304void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10305{
10306 if (!hdd_ctx->roaming_ini_original)
10307 return;
10308
10309 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10310
10311 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10312 CFG_LFR_FEATURE_ENABLED_MAX;
10313
10314 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10315
10316 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10317 CFG_LFR_FEATURE_ENABLED_MAX);
10318}
Anurag Chouhan83026002016-12-13 22:46:21 +053010319
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010320VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10321 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010322{
10323 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10324 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010325 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010327 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010328 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010329 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010330
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010331 if (pHddCtx->isLogpInProgress) {
10332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10333 "%s:LOGP in Progress. Ignore!!!",__func__);
10334 return VOS_STATUS_E_FAILURE;
10335 }
10336
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010338
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010339 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 switch(pAdapter->device_mode)
10341 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010342 case WLAN_HDD_IBSS:
10343 if ( VOS_TRUE == bCloseSession )
10344 {
10345 status = hdd_sta_id_hash_detach(pAdapter);
10346 if (status != VOS_STATUS_SUCCESS)
10347 hddLog(VOS_TRACE_LEVEL_ERROR,
10348 FL("sta id hash detach failed"));
10349 }
10350
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 case WLAN_HDD_INFRA_STATION:
10352 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010353 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010354 {
10355 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010356#ifdef FEATURE_WLAN_TDLS
10357 mutex_lock(&pHddCtx->tdls_lock);
10358 wlan_hdd_tdls_exit(pAdapter, TRUE);
10359 mutex_unlock(&pHddCtx->tdls_lock);
10360#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010361 if(hdd_connIsConnected(pstation) ||
10362 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 {
10364 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010365 {
10366 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10368 pAdapter->sessionId,
10369 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010370 /* Success implies disconnect command got queued up successfully
10371 * Or cmd not queued as scan for SSID is in progress
10372 */
10373 if((eHAL_STATUS_SUCCESS == halStatus) ||
10374 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10375 {
10376 ret = wait_for_completion_timeout(
10377 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010378 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010379 if (ret <= 0 &&
10380 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10381 {
10382 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010383 "%s: wait on disconnect_comp_var failed %ld",
10384 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010385 }
10386 }
10387 else
10388 {
10389 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10390 __func__);
10391 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010392 }
10393 else
10394 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010395 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 }
10397 memset(&wrqu, '\0', sizeof(wrqu));
10398 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10399 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10400 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10401 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010402 else if(pstation->conn_info.connState ==
10403 eConnectionState_Disconnecting)
10404 {
10405 ret = wait_for_completion_interruptible_timeout(
10406 &pAdapter->disconnect_comp_var,
10407 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10408 if (ret <= 0)
10409 {
10410 hddLog(VOS_TRACE_LEVEL_ERROR,
10411 FL("wait on disconnect_comp_var failed %ld"), ret);
10412 }
10413 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010414 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010416 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010418 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10419 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010420 {
10421 while (pAdapter->is_roc_inprogress)
10422 {
10423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10424 "%s: ROC in progress for session %d!!!",
10425 __func__, pAdapter->sessionId);
10426 // waiting for ROC to expire
10427 msleep(500);
10428 /* In GO present case , if retry exceeds 3,
10429 it means something went wrong. */
10430 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10431 {
10432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10433 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010434 if (eHAL_STATUS_SUCCESS !=
10435 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10436 pAdapter->sessionId ))
10437 {
10438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10439 FL("Failed to Cancel Remain on Channel"));
10440 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010441 wait_for_completion_interruptible_timeout(
10442 &pAdapter->cancel_rem_on_chan_var,
10443 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10444 break;
10445 }
10446 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010447 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010448 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010449#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010450 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010451#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010452
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010453 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010454
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010455 /* It is possible that the caller of this function does not
10456 * wish to close the session
10457 */
10458 if (VOS_TRUE == bCloseSession &&
10459 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 {
10461 INIT_COMPLETION(pAdapter->session_close_comp_var);
10462 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010463 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10464 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010466 unsigned long ret;
10467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010469 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010470 &pAdapter->session_close_comp_var,
10471 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010472 if ( 0 >= ret)
10473 {
10474 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010475 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010476 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 }
10478 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010479 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 break;
10481
10482 case WLAN_HDD_SOFTAP:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010483 /* Delete all associated STAs before stopping AP */
10484 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10485 hdd_del_all_sta(pAdapter);
10486 /* Fall through */
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 case WLAN_HDD_P2P_GO:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010488
Nirav Shah0cf4d892015-11-05 16:27:27 +053010489 if ( VOS_TRUE == bCloseSession )
10490 {
10491 status = hdd_sta_id_hash_detach(pAdapter);
10492 if (status != VOS_STATUS_SUCCESS)
10493 hddLog(VOS_TRACE_LEVEL_ERROR,
10494 FL("sta id hash detach failed"));
10495 }
10496
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010498 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010499 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10500 while (pAdapter->is_roc_inprogress) {
10501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10502 "%s: ROC in progress for session %d!!!",
10503 __func__, pAdapter->sessionId);
10504 msleep(500);
10505 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10507 "%s: ROC completion is not received.!!!", __func__);
10508 WLANSAP_CancelRemainOnChannel(
10509 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10510 wait_for_completion_interruptible_timeout(
10511 &pAdapter->cancel_rem_on_chan_var,
10512 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10513 break;
10514 }
10515 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010516
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010517 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010518 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010519#ifdef SAP_AUTH_OFFLOAD
10520 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10521 hdd_set_sap_auth_offload(pAdapter, FALSE);
10522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 mutex_lock(&pHddCtx->sap_lock);
10524 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10525 {
10526 VOS_STATUS status;
10527 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010528 hdd_hostapd_state_t *pHostapdState =
10529 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010530
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010531 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 //Stop Bss.
10533 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10534 if (VOS_IS_STATUS_SUCCESS(status))
10535 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10537
10538 if (!VOS_IS_STATUS_SUCCESS(status))
10539 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010540 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10541 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 }
10543 }
10544 else
10545 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010546 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010547 }
10548 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010549 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010550
10551 if (eHAL_STATUS_FAILURE ==
10552 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10553 0, NULL, eANI_BOOLEAN_FALSE))
10554 {
10555 hddLog(LOGE,
10556 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010557 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 }
10559
10560 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10561 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10562 eANI_BOOLEAN_FALSE) )
10563 {
10564 hddLog(LOGE,
10565 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10566 }
10567
10568 // Reset WNI_CFG_PROBE_RSP Flags
10569 wlan_hdd_reset_prob_rspies(pAdapter);
10570 kfree(pAdapter->sessionCtx.ap.beacon);
10571 pAdapter->sessionCtx.ap.beacon = NULL;
10572 }
10573 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010574
10575#ifdef WLAN_NS_OFFLOAD
10576 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10577#endif
10578 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010581
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010583 if (VOS_MONITOR_MODE != hdd_get_conparam())
10584 wlan_hdd_stop_mon(pHddCtx, true);
10585 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 default:
10588 break;
10589 }
10590
10591 EXIT();
10592 return VOS_STATUS_SUCCESS;
10593}
10594
Kapil Gupta137ef892016-12-13 19:38:00 +053010595/**
10596 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10597 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10598 *
10599 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10600 * After that WLANSAP_StartBss start re-start process of SAP.
10601 *
10602 * Return: None
10603 */
10604static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10605{
10606 hdd_ap_ctx_t *pHddApCtx;
10607 hdd_hostapd_state_t *pHostapdState;
10608 VOS_STATUS vos_status;
10609 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010610#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010611 struct station_del_parameters delStaParams;
10612#endif
10613 tsap_Config_t *pConfig;
10614
10615 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10616 pConfig = &pHddApCtx->sapConfig;
10617
10618 mutex_lock(&pHddCtx->sap_lock);
10619 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010620#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010621 delStaParams.mac = NULL;
10622 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10623 delStaParams.reason_code = eCsrForcedDeauthSta;
10624 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10625 &delStaParams);
10626#else
10627 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10628 NULL);
10629#endif
10630 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10631
10632 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10633 vos_event_reset(&pHostapdState->vosEvent);
10634
10635 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10636 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10637 10000);
10638 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10639 hddLog(LOGE, FL("SAP Stop Failed"));
10640 goto end;
10641 }
10642 }
10643 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10644 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10645 hddLog(LOG1, FL("SAP Stop Success"));
10646
10647 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10648 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10649 goto end;
10650 }
10651
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010652 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010653 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10654 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10655 hddLog(LOGE, FL("SAP Start Bss fail"));
10656 goto end;
10657 }
10658
10659 hddLog(LOG1, FL("Waiting for SAP to start"));
10660 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10661 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10662 hddLog(LOGE, FL("SAP Start failed"));
10663 goto end;
10664 }
10665 hddLog(LOG1, FL("SAP Start Success"));
10666 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10667 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10668 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010669 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10671 vos_event_reset(&pHostapdState->vosEvent);
10672 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10673 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10674 10000);
10675 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10676 hddLog(LOGE, FL("SAP Stop Failed"));
10677 goto end;
10678 }
10679 }
10680 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010681 }
10682end:
10683 mutex_unlock(&pHddCtx->sap_lock);
10684 return;
10685}
10686
10687/**
10688 * __hdd_sap_restart_handle() - to handle restarting of SAP
10689 * @work: name of the work
10690 *
10691 * Purpose of this function is to trigger sap start. this function
10692 * will be called from workqueue.
10693 *
10694 * Return: void.
10695 */
10696static void __hdd_sap_restart_handle(struct work_struct *work)
10697{
10698 hdd_adapter_t *sap_adapter;
10699 hdd_context_t *hdd_ctx = container_of(work,
10700 hdd_context_t,
10701 sap_start_work);
10702 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10703 vos_ssr_unprotect(__func__);
10704 return;
10705 }
10706 sap_adapter = hdd_get_adapter(hdd_ctx,
10707 WLAN_HDD_SOFTAP);
10708 if (sap_adapter == NULL) {
10709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10710 FL("sap_adapter is NULL"));
10711 vos_ssr_unprotect(__func__);
10712 return;
10713 }
10714
10715 if (hdd_ctx->is_ch_avoid_in_progress) {
10716 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10717 wlan_hdd_restart_sap(sap_adapter);
10718 hdd_change_ch_avoidance_status(hdd_ctx, false);
10719 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010720 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10721 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010722}
10723
10724/**
10725 * hdd_sap_restart_handle() - to handle restarting of SAP
10726 * @work: name of the work
10727 *
10728 * Purpose of this function is to trigger sap start. this function
10729 * will be called from workqueue.
10730 *
10731 * Return: void.
10732 */
10733static void hdd_sap_restart_handle(struct work_struct *work)
10734{
10735 vos_ssr_protect(__func__);
10736 __hdd_sap_restart_handle(work);
10737 vos_ssr_unprotect(__func__);
10738}
10739
10740
Abhishek Singh78c691f2017-11-30 13:48:44 +053010741/**
10742 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10743 * @work: name of the work
10744 *
10745 * Purpose of this function is to force SCC using ECSA. This function
10746 * will be called from workqueue.
10747 *
10748 * Return: void.
10749 */
10750static void
10751__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10752{
10753 hdd_adapter_t *sap_adapter;
10754 hdd_station_ctx_t *sta_ctx;
10755 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010756 ptSapContext sap_ctx = NULL;
10757 v_CONTEXT_t vos_ctx;
10758 tANI_U8 target_channel;
10759 tsap_Config_t *sap_config;
10760 bool sta_sap_scc_on_dfs_chan;
10761 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010762 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10763 hdd_context_t,
10764 ecsa_chan_change_work);
10765
10766 if (wlan_hdd_validate_context(hdd_ctx))
10767 return;
10768
10769 sap_adapter = hdd_get_adapter(hdd_ctx,
10770 WLAN_HDD_SOFTAP);
10771 if (!sap_adapter) {
10772 hddLog(LOGE, FL("sap_adapter is NULL"));
10773 return;
10774 }
10775
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010776 vos_ctx = hdd_ctx->pvosContext;
10777 if (!vos_ctx) {
10778 hddLog(LOGE, FL("vos_ctx is NULL"));
10779 return;
10780 }
10781
10782 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10783 if (!sap_ctx) {
10784 hddLog(LOGE, FL("sap_ctx is NULL"));
10785 return;
10786 }
10787
10788 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10789
10790 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10791
Abhishek Singh78c691f2017-11-30 13:48:44 +053010792 sta_adapter = hdd_get_adapter(hdd_ctx,
10793 WLAN_HDD_INFRA_STATION);
10794 if (!sta_adapter) {
10795 hddLog(LOGE, FL("sta_adapter is NULL"));
10796 return;
10797 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010798
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010799 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010800 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010801 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10802
10803 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10804 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10805 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10806 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10807 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10808 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10809 chan_state);
10810 if (sta_sap_scc_on_dfs_chan &&
10811 (chan_state == NV_CHANNEL_DFS)) {
10812 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10813 target_channel = sap_config->user_config_channel;
10814 goto switch_channel;
10815 }
10816 }
10817 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010818 }
10819
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010820 target_channel = sta_ctx->conn_info.operationChannel;
10821switch_channel:
10822 hddLog(LOGE, FL("Switch SAP to %d channel"),
10823 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010824 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10825 return;
10826
10827abort:
10828 wlansap_reset_chan_change_in_progress(sap_ctx);
10829 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010830}
10831
10832/**
10833 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10834 * @work: name of the work
10835 *
10836 * Purpose of this function is to force SCC using ECSA. This function
10837 * will be called from workqueue.
10838 *
10839 * Return: void.
10840 */
10841static void
10842hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10843{
10844 vos_ssr_protect(__func__);
10845 __hdd_force_scc_with_ecsa_handle(work);
10846 vos_ssr_unprotect(__func__);
10847}
10848
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010849int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10850{
10851 int ret;
10852 ptSapContext sap_ctx = NULL;
10853 v_CONTEXT_t vos_ctx;
10854
10855 vos_ctx = hdd_ctx->pvosContext;
10856 if (!vos_ctx) {
10857 hddLog(LOGE, FL("vos_ctx is NULL"));
10858 return 0;
10859 }
10860
10861 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10862 if (!sap_ctx) {
10863 hddLog(LOG1, FL("sap_ctx is NULL"));
10864 return 0;
10865 }
10866 if(!sap_ctx->isSapSessionOpen) {
10867 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10868 sap_ctx->sapsMachine);
10869 return 0;
10870 }
10871
10872 if (!wlansap_get_change_in_progress(sap_ctx)) {
10873 hddLog(LOG1, FL("channel switch not in progress"));
10874 return 0;
10875 }
10876 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10877 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10878 if (!ret)
10879 {
10880 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10881 return ret;
10882 }
10883
10884 return 0;
10885}
10886
10887
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010888/**
10889 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10890 * dfs chan
10891 * @hdd_ctx: pointer to hdd context
10892 *
10893 * This function used to check if sta+sap scc allowed on DFS channel.
10894 *
10895 * Return: None
10896 */
10897bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10898{
10899 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10900 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10901 return true;
10902 else
10903 return false;
10904}
10905
Jeff Johnson295189b2012-06-20 16:38:30 -070010906VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10907{
10908 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10909 VOS_STATUS status;
10910 hdd_adapter_t *pAdapter;
10911
10912 ENTER();
10913
10914 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10915
10916 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10917 {
10918 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010919
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010920 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010921
10922 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10923 pAdapterNode = pNext;
10924 }
10925
10926 EXIT();
10927
10928 return VOS_STATUS_SUCCESS;
10929}
10930
Rajeev Kumarf999e582014-01-09 17:33:29 -080010931
10932#ifdef FEATURE_WLAN_BATCH_SCAN
10933/**---------------------------------------------------------------------------
10934
10935 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10936 structures
10937
10938 \param - pAdapter Pointer to HDD adapter
10939
10940 \return - None
10941
10942 --------------------------------------------------------------------------*/
10943void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10944{
10945 tHddBatchScanRsp *pNode;
10946 tHddBatchScanRsp *pPrev;
10947
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010948 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010949 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010950 hddLog(VOS_TRACE_LEVEL_ERROR,
10951 "%s: Adapter context is Null", __func__);
10952 return;
10953 }
10954
10955 pNode = pAdapter->pBatchScanRsp;
10956 while (pNode)
10957 {
10958 pPrev = pNode;
10959 pNode = pNode->pNext;
10960 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010961 }
10962
10963 pAdapter->pBatchScanRsp = NULL;
10964 pAdapter->numScanList = 0;
10965 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10966 pAdapter->prev_batch_id = 0;
10967
10968 return;
10969}
10970#endif
10971
10972
Jeff Johnson295189b2012-06-20 16:38:30 -070010973VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10974{
10975 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10976 VOS_STATUS status;
10977 hdd_adapter_t *pAdapter;
10978
10979 ENTER();
10980
10981 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10982
10983 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10984 {
10985 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010986 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010988
10989 if (pHddCtx->cfg_ini->sap_internal_restart &&
10990 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10991 hddLog(LOG1, FL("driver supports sap restart"));
10992 vos_flush_work(&pHddCtx->sap_start_work);
10993 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10994 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010995 hdd_softap_deinit_tx_rx(pAdapter, true);
10996 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010997 } else {
10998 netif_carrier_off(pAdapter->dev);
10999 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011000
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011001 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011002
11003 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
11004 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011005
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011007
Katya Nigam1fd24402015-02-16 14:52:19 +053011008 if(pAdapter->device_mode == WLAN_HDD_IBSS )
11009 hdd_ibss_deinit_tx_rx(pAdapter);
11010
Nirav Shah7e3c8132015-06-22 23:51:42 +053011011 status = hdd_sta_id_hash_detach(pAdapter);
11012 if (status != VOS_STATUS_SUCCESS)
11013 hddLog(VOS_TRACE_LEVEL_ERROR,
11014 FL("sta id hash detach failed for session id %d"),
11015 pAdapter->sessionId);
11016
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011017 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11018
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011019 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11020 {
11021 hdd_wmm_adapter_close( pAdapter );
11022 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011024
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011025 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11026 {
11027 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11028 }
11029
Rajeev Kumarf999e582014-01-09 17:33:29 -080011030#ifdef FEATURE_WLAN_BATCH_SCAN
11031 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11032 {
11033 hdd_deinit_batch_scan(pAdapter);
11034 }
11035#endif
11036
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011037#ifdef FEATURE_WLAN_TDLS
11038 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011039 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011040 mutex_unlock(&pHddCtx->tdls_lock);
11041#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11043 pAdapterNode = pNext;
11044 }
11045
11046 EXIT();
11047
11048 return VOS_STATUS_SUCCESS;
11049}
11050
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011051/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011052 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11053 * @wiphy: wiphy
11054 * @channel: channel of the BSS to find
11055 * @bssid: bssid of the BSS to find
11056 * @ssid: ssid of the BSS to find
11057 * @ssid_len: ssid len of of the BSS to find
11058 *
11059 * The API is a wrapper to get bss from kernel matching the chan,
11060 * bssid and ssid
11061 *
11062 * Return: Void
11063 */
11064#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11065 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11066
11067struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11068 struct ieee80211_channel *channel,
11069 const u8 *bssid,
11070 const u8 *ssid, size_t ssid_len)
11071{
11072 return cfg80211_get_bss(wiphy, channel, bssid,
11073 ssid, ssid_len,
11074 WLAN_CAPABILITY_ESS,
11075 WLAN_CAPABILITY_ESS);
11076}
11077#else
11078struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11079 struct ieee80211_channel *channel,
11080 const u8 *bssid,
11081 const u8 *ssid, size_t ssid_len)
11082{
11083 return cfg80211_get_bss(wiphy, channel, bssid,
11084 ssid, ssid_len,
11085 IEEE80211_BSS_TYPE_ESS,
11086 IEEE80211_PRIVACY_ANY);
11087}
11088#endif
11089
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011090#if defined(CFG80211_CONNECT_BSS) || \
11091 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11092
11093#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11094 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11095/**
11096 * hdd_connect_bss() - helper function to send connection status to supplicant
11097 * @dev: network device
11098 * @bssid: bssid to which we want to associate
11099 * @bss: information about connected bss
11100 * @req_ie: Request Information Element
11101 * @req_ie_len: len of the req IE
11102 * @resp_ie: Response IE
11103 * @resp_ie_len: len of ht response IE
11104 * @status: status
11105 * @gfp: Kernel Flag
11106 *
11107 * This is a helper function to send connection status to supplicant
11108 * and gets invoked from wrapper API
11109 *
11110 * Return: Void
11111 */
11112static void hdd_connect_bss(struct net_device *dev,
11113 const u8 *bssid,
11114 struct cfg80211_bss *bss,
11115 const u8 *req_ie,
11116 size_t req_ie_len,
11117 const u8 *resp_ie,
11118 size_t resp_ie_len,
11119 u16 status,
11120 gfp_t gfp)
11121{
11122 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11123 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11124}
11125#else
11126/**
11127 * hdd_connect_bss() - helper function to send connection status to supplicant
11128 * @dev: network device
11129 * @bssid: bssid to which we want to associate
11130 * @bss: information about connected bss
11131 * @req_ie: Request Information Element
11132 * @req_ie_len: len of the req IE
11133 * @resp_ie: Response IE
11134 * @resp_ie_len: len of ht response IE
11135 * @status: status
11136 * @gfp: Kernel Flag
11137 *
11138 * This is a helper function to send connection status to supplicant
11139 * and gets invoked from wrapper API
11140 *
11141 * Return: Void
11142 */
11143static void hdd_connect_bss(struct net_device *dev,
11144 const u8 *bssid,
11145 struct cfg80211_bss *bss,
11146 const u8 *req_ie,
11147 size_t req_ie_len,
11148 const u8 *resp_ie,
11149 size_t resp_ie_len,
11150 u16 status,
11151 gfp_t gfp)
11152{
11153 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11154 resp_ie, resp_ie_len, status, gfp);
11155}
11156#endif
11157
Abhishek Singh5a597e62016-12-05 15:16:30 +053011158/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011159 * hdd_connect_result() - API to send connection status to supplicant
11160 * @dev: network device
11161 * @bssid: bssid to which we want to associate
11162 * @roam_info: information about connected bss
11163 * @req_ie: Request Information Element
11164 * @req_ie_len: len of the req IE
11165 * @resp_ie: Response IE
11166 * @resp_ie_len: len of ht response IE
11167 * @status: status
11168 * @gfp: Kernel Flag
11169 *
11170 * The API is a wrapper to send connection status to supplicant
11171 *
11172 * Return: Void
11173 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011174void hdd_connect_result(struct net_device *dev,
11175 const u8 *bssid,
11176 tCsrRoamInfo *roam_info,
11177 const u8 *req_ie,
11178 size_t req_ie_len,
11179 const u8 *resp_ie,
11180 size_t resp_ie_len,
11181 u16 status,
11182 gfp_t gfp)
11183{
11184 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11185 struct cfg80211_bss *bss = NULL;
11186
11187 if (WLAN_STATUS_SUCCESS == status) {
11188 struct ieee80211_channel *chan;
11189 int freq;
11190 int chan_no = roam_info->pBssDesc->channelId;;
11191
11192 if (chan_no <= 14)
11193 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011194 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011195 else
11196 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011197 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011198
11199 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011200 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11201 chan, bssid,
11202 roam_info->u.pConnectedProfile->SSID.ssId,
11203 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011204 }
11205
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011206 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11207 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011208}
11209#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011210/**
11211 * hdd_connect_result() - API to send connection status to supplicant
11212 * @dev: network device
11213 * @bssid: bssid to which we want to associate
11214 * @roam_info: information about connected bss
11215 * @req_ie: Request Information Element
11216 * @req_ie_len: len of the req IE
11217 * @resp_ie: Response IE
11218 * @resp_ie_len: len of ht response IE
11219 * @status: status
11220 * @gfp: Kernel Flag
11221 *
11222 * The API is a wrapper to send connection status to supplicant
11223 *
11224 * Return: Void
11225 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011226void hdd_connect_result(struct net_device *dev,
11227 const u8 *bssid,
11228 tCsrRoamInfo *roam_info,
11229 const u8 *req_ie,
11230 size_t req_ie_len,
11231 const u8 * resp_ie,
11232 size_t resp_ie_len,
11233 u16 status,
11234 gfp_t gfp)
11235{
11236 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11237 resp_ie, resp_ie_len, status, gfp);
11238}
11239#endif
11240
Jeff Johnson295189b2012-06-20 16:38:30 -070011241VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11242{
11243 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11244 VOS_STATUS status;
11245 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011246 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011247 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 ENTER();
11250
11251 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11252
11253 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11254 {
11255 pAdapter = pAdapterNode->pAdapter;
11256
Kumar Anand82c009f2014-05-29 00:29:42 -070011257 hdd_wmm_init( pAdapter );
11258
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 switch(pAdapter->device_mode)
11260 {
11261 case WLAN_HDD_INFRA_STATION:
11262 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011263 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011264
11265 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11266
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 hdd_init_station_mode(pAdapter);
11268 /* Open the gates for HDD to receive Wext commands */
11269 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011270 pHddCtx->scan_info.mScanPending = FALSE;
11271 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011272
11273 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011274 if (!pHddCtx->isLogpInProgress)
11275 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011276
11277 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011278 if (eConnectionState_Associated == connState ||
11279 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 {
11281 union iwreq_data wrqu;
11282 memset(&wrqu, '\0', sizeof(wrqu));
11283 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11284 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11285 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011286 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011287
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011289 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011290 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011292 else if (eConnectionState_Connecting == connState)
11293 {
11294 /*
11295 * Indicate connect failure to supplicant if we were in the
11296 * process of connecting
11297 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011298 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011299 NULL, 0, NULL, 0,
11300 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11301 GFP_KERNEL);
11302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 break;
11304
11305 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011306 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011307 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011308 status = hdd_sta_id_hash_attach(pAdapter);
11309 if (VOS_STATUS_SUCCESS != status)
11310 {
11311 hddLog(VOS_TRACE_LEVEL_FATAL,
11312 FL("failed to attach hash for"));
11313 }
11314 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 break;
11316
11317 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011320 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 break;
11322
11323 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011324 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11325
11326 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11327 if (!pVosContext) {
11328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11329 break;
11330 }
11331
11332 hdd_init_tx_rx(pAdapter);
11333 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011335
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 default:
11337 break;
11338 }
11339
11340 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11341 pAdapterNode = pNext;
11342 }
11343
11344 EXIT();
11345
11346 return VOS_STATUS_SUCCESS;
11347}
11348
11349VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11350{
11351 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11352 hdd_adapter_t *pAdapter;
11353 VOS_STATUS status;
11354 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011355 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011356
11357 ENTER();
11358
11359 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11360
11361 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11362 {
11363 pAdapter = pAdapterNode->pAdapter;
11364
11365 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11366 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11367 {
11368 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11369 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11370
Abhishek Singhf4669da2014-05-26 15:07:49 +053011371 hddLog(VOS_TRACE_LEVEL_INFO,
11372 "%s: Set HDD connState to eConnectionState_NotConnected",
11373 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011374 spin_lock_bh(&pAdapter->lock_for_active_session);
11375 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11376 {
11377 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11378 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011380 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 init_completion(&pAdapter->disconnect_comp_var);
11382 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11383 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11384
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011385 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 &pAdapter->disconnect_comp_var,
11387 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011388 if (0 >= ret)
11389 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11390 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011391
11392 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11393 pHddCtx->isAmpAllowed = VOS_FALSE;
11394 sme_RoamConnect(pHddCtx->hHal,
11395 pAdapter->sessionId, &(pWextState->roamProfile),
11396 &roamId);
11397 }
11398
11399 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11400 pAdapterNode = pNext;
11401 }
11402
11403 EXIT();
11404
11405 return VOS_STATUS_SUCCESS;
11406}
11407
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011408void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11409{
11410 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11411 VOS_STATUS status;
11412 hdd_adapter_t *pAdapter;
11413 hdd_station_ctx_t *pHddStaCtx;
11414 hdd_ap_ctx_t *pHddApCtx;
11415 hdd_hostapd_state_t * pHostapdState;
11416 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11417 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11418 const char *p2pMode = "DEV";
11419 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011420
11421 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11422 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11423 {
11424 pAdapter = pAdapterNode->pAdapter;
11425 switch (pAdapter->device_mode) {
11426 case WLAN_HDD_INFRA_STATION:
11427 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11428 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11429 staChannel = pHddStaCtx->conn_info.operationChannel;
11430 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11431 }
11432 break;
11433 case WLAN_HDD_P2P_CLIENT:
11434 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11435 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11436 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11437 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11438 p2pMode = "CLI";
11439 }
11440 break;
11441 case WLAN_HDD_P2P_GO:
11442 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11443 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11444 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11445 p2pChannel = pHddApCtx->operatingChannel;
11446 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11447 }
11448 p2pMode = "GO";
11449 break;
11450 case WLAN_HDD_SOFTAP:
11451 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11452 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11453 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11454 apChannel = pHddApCtx->operatingChannel;
11455 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11456 }
11457 break;
11458 default:
11459 break;
11460 }
11461 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11462 pAdapterNode = pNext;
11463 }
11464 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11465 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11466 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011467 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11468 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011469 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011470 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011471 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11472 }
11473 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011474 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011475 apChannel, MAC_ADDR_ARRAY(apBssid));
11476 }
11477
11478 if (p2pChannel > 0 && apChannel > 0) {
11479 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11480 }
11481}
11482
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011483bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011484{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011485 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011486}
11487
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011488/* Once SSR is disabled then it cannot be set. */
11489void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011490{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011491 if (HDD_SSR_DISABLED == isSsrRequired)
11492 return;
11493
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 isSsrRequired = value;
11495}
11496
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011497void hdd_set_pre_close( hdd_context_t *pHddCtx)
11498{
11499 sme_PreClose(pHddCtx->hHal);
11500}
11501
Jeff Johnson295189b2012-06-20 16:38:30 -070011502VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11503 hdd_adapter_list_node_t** ppAdapterNode)
11504{
11505 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011506 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11508 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011509 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 return status;
11511}
11512
11513VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11514 hdd_adapter_list_node_t* pAdapterNode,
11515 hdd_adapter_list_node_t** pNextAdapterNode)
11516{
11517 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011518 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11520 (hdd_list_node_t*) pAdapterNode,
11521 (hdd_list_node_t**)pNextAdapterNode );
11522
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011523 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 return status;
11525}
11526
11527VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11528 hdd_adapter_list_node_t* pAdapterNode)
11529{
11530 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011531 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11533 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011534 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 return status;
11536}
11537
11538VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11539 hdd_adapter_list_node_t** ppAdapterNode)
11540{
11541 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011542 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11544 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011545 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 return status;
11547}
11548
11549VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11550 hdd_adapter_list_node_t* pAdapterNode)
11551{
11552 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011553 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11555 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011556 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 return status;
11558}
11559
11560VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11561 hdd_adapter_list_node_t* pAdapterNode)
11562{
11563 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011564 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11566 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011567 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 return status;
11569}
11570
11571hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11572 tSirMacAddr macAddr )
11573{
11574 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11575 hdd_adapter_t *pAdapter;
11576 VOS_STATUS status;
11577
11578 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11579
11580 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11581 {
11582 pAdapter = pAdapterNode->pAdapter;
11583
11584 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11585 macAddr, sizeof(tSirMacAddr) ) )
11586 {
11587 return pAdapter;
11588 }
11589 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11590 pAdapterNode = pNext;
11591 }
11592
11593 return NULL;
11594
11595}
11596
11597hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11598{
11599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11600 hdd_adapter_t *pAdapter;
11601 VOS_STATUS status;
11602
11603 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11604
11605 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11606 {
11607 pAdapter = pAdapterNode->pAdapter;
11608
11609 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11610 IFNAMSIZ ) )
11611 {
11612 return pAdapter;
11613 }
11614 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11615 pAdapterNode = pNext;
11616 }
11617
11618 return NULL;
11619
11620}
11621
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011622hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11623 tANI_U32 sme_session_id )
11624{
11625 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11626 hdd_adapter_t *pAdapter;
11627 VOS_STATUS vos_status;
11628
11629
11630 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11631
11632 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11633 {
11634 pAdapter = pAdapterNode->pAdapter;
11635
11636 if (pAdapter->sessionId == sme_session_id)
11637 return pAdapter;
11638
11639 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11640 pAdapterNode = pNext;
11641 }
11642
11643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11644 "%s: sme_session_id %d does not exist with host",
11645 __func__, sme_session_id);
11646
11647 return NULL;
11648}
11649
Jeff Johnson295189b2012-06-20 16:38:30 -070011650hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11651{
11652 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11653 hdd_adapter_t *pAdapter;
11654 VOS_STATUS status;
11655
11656 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11657
11658 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11659 {
11660 pAdapter = pAdapterNode->pAdapter;
11661
11662 if( pAdapter && (mode == pAdapter->device_mode) )
11663 {
11664 return pAdapter;
11665 }
11666 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11667 pAdapterNode = pNext;
11668 }
11669
11670 return NULL;
11671
11672}
11673
11674//Remove this function later
11675hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11676{
11677 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11678 hdd_adapter_t *pAdapter;
11679 VOS_STATUS status;
11680
11681 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11682
11683 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11684 {
11685 pAdapter = pAdapterNode->pAdapter;
11686
11687 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11688 {
11689 return pAdapter;
11690 }
11691
11692 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11693 pAdapterNode = pNext;
11694 }
11695
11696 return NULL;
11697
11698}
11699
Jeff Johnson295189b2012-06-20 16:38:30 -070011700/**---------------------------------------------------------------------------
11701
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011702 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011703
11704 This API returns the operating channel of the requested device mode
11705
11706 \param - pHddCtx - Pointer to the HDD context.
11707 - mode - Device mode for which operating channel is required
11708 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11709 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11710 \return - channel number. "0" id the requested device is not found OR it is not connected.
11711 --------------------------------------------------------------------------*/
11712v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11713{
11714 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11715 VOS_STATUS status;
11716 hdd_adapter_t *pAdapter;
11717 v_U8_t operatingChannel = 0;
11718
11719 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11720
11721 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11722 {
11723 pAdapter = pAdapterNode->pAdapter;
11724
11725 if( mode == pAdapter->device_mode )
11726 {
11727 switch(pAdapter->device_mode)
11728 {
11729 case WLAN_HDD_INFRA_STATION:
11730 case WLAN_HDD_P2P_CLIENT:
11731 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11732 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11733 break;
11734 case WLAN_HDD_SOFTAP:
11735 case WLAN_HDD_P2P_GO:
11736 /*softap connection info */
11737 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11738 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11739 break;
11740 default:
11741 break;
11742 }
11743
11744 break; //Found the device of interest. break the loop
11745 }
11746
11747 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11748 pAdapterNode = pNext;
11749 }
11750 return operatingChannel;
11751}
11752
11753#ifdef WLAN_FEATURE_PACKET_FILTERING
11754/**---------------------------------------------------------------------------
11755
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011756 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011757
11758 This used to set the multicast address list.
11759
11760 \param - dev - Pointer to the WLAN device.
11761 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011762 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011763
11764 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011765static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011766{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011767 hdd_adapter_t *pAdapter;
11768 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011770 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011773 ENTER();
11774
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011775 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011776 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 {
11778 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011779 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 return;
11781 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11783 ret = wlan_hdd_validate_context(pHddCtx);
11784 if (0 != ret)
11785 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011786 return;
11787 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 if (dev->flags & IFF_ALLMULTI)
11789 {
11790 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011791 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011792 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011794 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 {
11796 mc_count = netdev_mc_count(dev);
11797 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011798 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11800 {
11801 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011802 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011803 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 return;
11805 }
11806
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011807 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011808
11809 netdev_for_each_mc_addr(ha, dev) {
11810 if (i == mc_count)
11811 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011812 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11813 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011815 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011816 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 i++;
11818 }
11819 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011820
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011821 if (pHddCtx->hdd_wlan_suspended)
11822 {
11823 /*
11824 * Configure the Mcast address list to FW
11825 * If wlan is already in suspend mode
11826 */
11827 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11828 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011829 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 return;
11831}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011832
11833static void hdd_set_multicast_list(struct net_device *dev)
11834{
11835 vos_ssr_protect(__func__);
11836 __hdd_set_multicast_list(dev);
11837 vos_ssr_unprotect(__func__);
11838}
Jeff Johnson295189b2012-06-20 16:38:30 -070011839#endif
11840
11841/**---------------------------------------------------------------------------
11842
11843 \brief hdd_select_queue() -
11844
11845 This function is registered with the Linux OS for network
11846 core to decide which queue to use first.
11847
11848 \param - dev - Pointer to the WLAN device.
11849 - skb - Pointer to OS packet (sk_buff).
11850 \return - ac, Queue Index/access category corresponding to UP in IP header
11851
11852 --------------------------------------------------------------------------*/
11853v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011854 struct sk_buff *skb
11855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11856 , void *accel_priv
11857#endif
11858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11859 , select_queue_fallback_t fallback
11860#endif
11861)
Jeff Johnson295189b2012-06-20 16:38:30 -070011862{
11863 return hdd_wmm_select_queue(dev, skb);
11864}
11865
11866
11867/**---------------------------------------------------------------------------
11868
11869 \brief hdd_wlan_initial_scan() -
11870
11871 This function triggers the initial scan
11872
11873 \param - pAdapter - Pointer to the HDD adapter.
11874
11875 --------------------------------------------------------------------------*/
11876void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11877{
11878 tCsrScanRequest scanReq;
11879 tCsrChannelInfo channelInfo;
11880 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011881 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011882 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11883
11884 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11885 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11886 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11887
11888 if(sme_Is11dSupported(pHddCtx->hHal))
11889 {
11890 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11891 if ( HAL_STATUS_SUCCESS( halStatus ) )
11892 {
11893 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11894 if( !scanReq.ChannelInfo.ChannelList )
11895 {
11896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11897 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011898 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 return;
11900 }
11901 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11902 channelInfo.numOfChannels);
11903 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11904 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011905 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 }
11907
11908 scanReq.scanType = eSIR_PASSIVE_SCAN;
11909 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11910 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11911 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11912 }
11913 else
11914 {
11915 scanReq.scanType = eSIR_ACTIVE_SCAN;
11916 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11917 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11918 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11919 }
11920
11921 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11922 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11923 {
11924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11925 __func__, halStatus );
11926 }
11927
11928 if(sme_Is11dSupported(pHddCtx->hHal))
11929 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11930}
11931
Jeff Johnson295189b2012-06-20 16:38:30 -070011932/**---------------------------------------------------------------------------
11933
11934 \brief hdd_full_power_callback() - HDD full power callback function
11935
11936 This is the function invoked by SME to inform the result of a full power
11937 request issued by HDD
11938
11939 \param - callbackcontext - Pointer to cookie
11940 \param - status - result of request
11941
11942 \return - None
11943
11944 --------------------------------------------------------------------------*/
11945static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11946{
Jeff Johnson72a40512013-12-19 10:14:15 -080011947 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011948
11949 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011950 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011951
11952 if (NULL == callbackContext)
11953 {
11954 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011955 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011956 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 return;
11958 }
11959
Jeff Johnson72a40512013-12-19 10:14:15 -080011960 /* there is a race condition that exists between this callback
11961 function and the caller since the caller could time out either
11962 before or while this code is executing. we use a spinlock to
11963 serialize these actions */
11964 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011965
11966 if (POWER_CONTEXT_MAGIC != pContext->magic)
11967 {
11968 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011969 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 hddLog(VOS_TRACE_LEVEL_WARN,
11971 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011972 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 return;
11974 }
11975
Jeff Johnson72a40512013-12-19 10:14:15 -080011976 /* context is valid so caller is still waiting */
11977
11978 /* paranoia: invalidate the magic */
11979 pContext->magic = 0;
11980
11981 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011983
11984 /* serialization is complete */
11985 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011986}
11987
Katya Nigamf0511f62015-05-05 16:40:57 +053011988void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11989{
11990 pMonCtx->typeSubtypeBitmap = 0;
11991 if( type%10 ) /* Management Packets */
11992 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11993 type/=10;
11994 if( type%10 ) /* Control Packets */
11995 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11996 type/=10;
11997 if( type%10 ) /* Data Packets */
11998 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11999}
12000
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012001VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
12002 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053012003{
12004 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012005 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012006
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012007 if (MON_MODE_START == pMonCtx->state)
12008 monMsg.type = WDA_MON_START_REQ;
12009 else if (MON_MODE_STOP == pMonCtx->state)
12010 monMsg.type = WDA_MON_STOP_REQ;
12011 else {
12012 hddLog(VOS_TRACE_LEVEL_ERROR,
12013 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053012014 return VOS_STATUS_E_FAILURE;
12015 }
12016
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012017 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12018 if (pMonModeReq == NULL) {
12019 hddLog(VOS_TRACE_LEVEL_ERROR,
12020 FL("fail to allocate memory for monitor mode req"));
12021 return VOS_STATUS_E_FAILURE;
12022 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012023
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012024 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012025 pMonModeReq->data = pMonCtx;
12026 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012027
Katya Nigamf0511f62015-05-05 16:40:57 +053012028 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012029 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012030 monMsg.bodyval = 0;
12031
12032 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12033 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12034 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012035 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012036 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012037 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012038}
12039
Katya Nigame7b69a82015-04-28 15:24:06 +053012040void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12041{
12042 VOS_STATUS vosStatus;
12043 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012044 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012045 int ret;
12046 void *cookie;
12047 struct hdd_request *request;
12048 static const struct hdd_request_params params = {
12049 .priv_size = 0,
12050 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12051 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012052
Katya Nigame7b69a82015-04-28 15:24:06 +053012053 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12054 if(pAdapter == NULL || pVosContext == NULL)
12055 {
12056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12057 return ;
12058 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012059
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012060 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12061 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12062 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012063 request = hdd_request_alloc(&params);
12064 if (!request) {
12065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12066 return;
12067 }
12068 cookie = hdd_request_cookie(request);
12069
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012070 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012071 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12072 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12074 FL("failed to post MON MODE REQ"));
12075 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012076 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012077 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012078
12079 ret = hdd_request_wait_for_response(request);
12080 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012082 FL("timeout on monitor mode completion %d"), ret);
12083
12084req_put:
12085 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012086 }
12087
Katya Nigame7b69a82015-04-28 15:24:06 +053012088 hdd_UnregisterWext(pAdapter->dev);
12089
12090 vos_mon_stop( pVosContext );
12091
12092 vosStatus = vos_sched_close( pVosContext );
12093 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12094 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12095 "%s: Failed to close VOSS Scheduler",__func__);
12096 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12097 }
12098
12099 vosStatus = vos_nv_close();
12100 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12101 {
12102 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12103 "%s: Failed to close NV", __func__);
12104 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12105 }
12106
12107 vos_close(pVosContext);
12108
12109 #ifdef WLAN_KD_READY_NOTIFIER
12110 nl_srv_exit(pHddCtx->ptt_pid);
12111 #else
12112 nl_srv_exit();
12113 #endif
12114
Katya Nigame7b69a82015-04-28 15:24:06 +053012115 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012116}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012117/**
12118 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12119 * @ wiphy: the wiphy to validate against
12120 *
12121 * Return: void
12122 */
12123void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12124{
12125 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012126 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012127 {
12128 if (NULL != wiphy->bands[i] &&
12129 (NULL != wiphy->bands[i]->channels))
12130 {
12131 vos_mem_free(wiphy->bands[i]->channels);
12132 wiphy->bands[i]->channels = NULL;
12133 }
12134 }
12135}
Jeff Johnson295189b2012-06-20 16:38:30 -070012136/**---------------------------------------------------------------------------
12137
12138 \brief hdd_wlan_exit() - HDD WLAN exit function
12139
12140 This is the driver exit point (invoked during rmmod)
12141
12142 \param - pHddCtx - Pointer to the HDD Context
12143
12144 \return - None
12145
12146 --------------------------------------------------------------------------*/
12147void hdd_wlan_exit(hdd_context_t *pHddCtx)
12148{
12149 eHalStatus halStatus;
12150 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12151 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012152 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012153 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012154 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012155 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012156 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012157
12158 ENTER();
12159
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012160
Katya Nigame7b69a82015-04-28 15:24:06 +053012161 if (VOS_MONITOR_MODE == hdd_get_conparam())
12162 {
12163 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12164 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012165 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012166 }
12167 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012168 {
12169 // Unloading, restart logic is no more required.
12170 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012171
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012172#ifdef FEATURE_WLAN_TDLS
12173 /* At the time of driver unloading; if tdls connection is present;
12174 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12175 * wlan_hdd_tdls_find_peer always checks for valid context;
12176 * as load/unload in progress there can be a race condition.
12177 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12178 * when tdls state is enabled.
12179 * As soon as driver set load/unload flag; tdls flag also needs
12180 * to be disabled so that hdd_rx_packet_cbk won't call
12181 * wlan_hdd_tdls_find_peer.
12182 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012183 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12184 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012185#endif
12186
c_hpothu5ab05e92014-06-13 17:34:05 +053012187 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12188 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012190 pAdapter = pAdapterNode->pAdapter;
12191 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012193 /* Disable TX on the interface, after this hard_start_xmit() will
12194 * not be called on that interface
12195 */
12196 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12197 netif_tx_disable(pAdapter->dev);
12198
12199 /* Mark the interface status as "down" for outside world */
12200 netif_carrier_off(pAdapter->dev);
12201
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012202 /* DeInit the adapter. This ensures that all data packets
12203 * are freed.
12204 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012205#ifdef FEATURE_WLAN_TDLS
12206 mutex_lock(&pHddCtx->tdls_lock);
12207#endif
c_hpothu002231a2015-02-05 14:58:51 +053012208 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012209#ifdef FEATURE_WLAN_TDLS
12210 mutex_unlock(&pHddCtx->tdls_lock);
12211#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012212 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12213
12214 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012215
c_hpothu5ab05e92014-06-13 17:34:05 +053012216 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012217 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12218 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012219 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012220 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12221 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12222 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12223
c_hpothu5ab05e92014-06-13 17:34:05 +053012224 hdd_UnregisterWext(pAdapter->dev);
12225 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012226
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012228 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12229 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 }
mukul sharmabab477d2015-06-11 17:14:55 +053012231
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012232 // Cancel any outstanding scan requests. We are about to close all
12233 // of our adapters, but an adapter structure is what SME passes back
12234 // to our callback function. Hence if there are any outstanding scan
12235 // requests then there is a race condition between when the adapter
12236 // is closed and when the callback is invoked.We try to resolve that
12237 // race condition here by canceling any outstanding scans before we
12238 // close the adapters.
12239 // Note that the scans may be cancelled in an asynchronous manner,
12240 // so ideally there needs to be some kind of synchronization. Rather
12241 // than introduce a new synchronization here, we will utilize the
12242 // fact that we are about to Request Full Power, and since that is
12243 // synchronized, the expectation is that by the time Request Full
12244 // Power has completed all scans will be cancelled.
12245 if (pHddCtx->scan_info.mScanPending)
12246 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012247 if(NULL != pAdapter)
12248 {
12249 hddLog(VOS_TRACE_LEVEL_INFO,
12250 FL("abort scan mode: %d sessionId: %d"),
12251 pAdapter->device_mode,
12252 pAdapter->sessionId);
12253 }
12254 hdd_abort_mac_scan(pHddCtx,
12255 pHddCtx->scan_info.sessionId,
12256 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012259 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012260 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012261 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012262 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12263 {
12264 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12266 "%s: in middle of FTM START", __func__);
12267 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12268 msecs_to_jiffies(20000));
12269 if(!lrc)
12270 {
12271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12272 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12273 }
12274 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012275 wlan_hdd_ftm_close(pHddCtx);
12276 goto free_hdd_ctx;
12277 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012278
Jeff Johnson295189b2012-06-20 16:38:30 -070012279 /* DeRegister with platform driver as client for Suspend/Resume */
12280 vosStatus = hddDeregisterPmOps(pHddCtx);
12281 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12282 {
12283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12284 VOS_ASSERT(0);
12285 }
12286
12287 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12288 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12289 {
12290 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012292
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012293 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012294 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12295 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012296 {
12297 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12298 }
12299
12300 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012301 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12302 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12303 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012304 {
12305 hddLog(VOS_TRACE_LEVEL_ERROR,
12306 "%s: Cannot deallocate Traffic monitor timer", __func__);
12307 }
12308
Bhargav Shahd0715912015-10-01 18:17:37 +053012309 if (VOS_TIMER_STATE_RUNNING ==
12310 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12311 vos_timer_stop(&pHddCtx->delack_timer);
12312 }
12313
12314 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12315 &pHddCtx->delack_timer))) {
12316 hddLog(VOS_TRACE_LEVEL_ERROR,
12317 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12318 }
12319
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012320 if (VOS_TIMER_STATE_RUNNING ==
12321 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12322 vos_timer_stop(&pHddCtx->tdls_source_timer);
12323 }
12324
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012325 vos_set_snoc_high_freq_voting(false);
12326
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012327 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12328
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 //Disable IMPS/BMPS as we do not want the device to enter any power
12330 //save mode during shutdown
12331 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12332 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12333 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12334
12335 //Ensure that device is in full power as we will touch H/W during vos_Stop
12336 init_completion(&powerContext.completion);
12337 powerContext.magic = POWER_CONTEXT_MAGIC;
12338
12339 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12340 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12341
12342 if (eHAL_STATUS_SUCCESS != halStatus)
12343 {
12344 if (eHAL_STATUS_PMC_PENDING == halStatus)
12345 {
12346 /* request was sent -- wait for the response */
12347 lrc = wait_for_completion_interruptible_timeout(
12348 &powerContext.completion,
12349 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 if (lrc <= 0)
12351 {
12352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012353 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 }
12355 }
12356 else
12357 {
12358 hddLog(VOS_TRACE_LEVEL_ERROR,
12359 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012360 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 /* continue -- need to clean up as much as possible */
12362 }
12363 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012364 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12365 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12366 {
12367 /* This will issue a dump command which will clean up
12368 BTQM queues and unblock MC thread */
12369 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012371
Jeff Johnson72a40512013-12-19 10:14:15 -080012372 /* either we never sent a request, we sent a request and received a
12373 response or we sent a request and timed out. if we never sent a
12374 request or if we sent a request and got a response, we want to
12375 clear the magic out of paranoia. if we timed out there is a
12376 race condition such that the callback function could be
12377 executing at the same time we are. of primary concern is if the
12378 callback function had already verified the "magic" but had not
12379 yet set the completion variable when a timeout occurred. we
12380 serialize these activities by invalidating the magic while
12381 holding a shared spinlock which will cause us to block if the
12382 callback is currently executing */
12383 spin_lock(&hdd_context_lock);
12384 powerContext.magic = 0;
12385 spin_unlock(&hdd_context_lock);
12386
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012387 /* If Device is shutdown, no point for SME to wait for responses
12388 from device. Pre Close SME */
12389 if(wcnss_device_is_shutdown())
12390 {
12391 sme_PreClose(pHddCtx->hHal);
12392 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012393 hdd_debugfs_exit(pHddCtx);
12394
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012395#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012396 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012397 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12398#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012399 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012400 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12401
Jeff Johnson295189b2012-06-20 16:38:30 -070012402 // Unregister the Net Device Notifier
12403 unregister_netdevice_notifier(&hdd_netdev_notifier);
12404
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 hdd_stop_all_adapters( pHddCtx );
12406
Jeff Johnson295189b2012-06-20 16:38:30 -070012407#ifdef WLAN_BTAMP_FEATURE
12408 vosStatus = WLANBAP_Stop(pVosContext);
12409 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12410 {
12411 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12412 "%s: Failed to stop BAP",__func__);
12413 }
12414#endif //WLAN_BTAMP_FEATURE
12415
12416 //Stop all the modules
12417 vosStatus = vos_stop( pVosContext );
12418 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12419 {
12420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12421 "%s: Failed to stop VOSS",__func__);
12422 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012423 if (isSsrPanicOnFailure())
12424 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 }
12426
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
12430 //Close the scheduler before calling vos_close to make sure no thread is
12431 // scheduled after the each module close is called i.e after all the data
12432 // structures are freed.
12433 vosStatus = vos_sched_close( pVosContext );
12434 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12435 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12436 "%s: Failed to close VOSS Scheduler",__func__);
12437 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12438 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012439#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12440 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012441 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012442#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012443 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012444 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012445
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012446#ifdef CONFIG_ENABLE_LINUX_REG
12447 vosStatus = vos_nv_close();
12448 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12449 {
12450 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12451 "%s: Failed to close NV", __func__);
12452 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12453 }
12454#endif
12455
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 //Close VOSS
12457 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12458 vos_close(pVosContext);
12459
Jeff Johnson295189b2012-06-20 16:38:30 -070012460 //Close Watchdog
12461 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12462 vos_watchdog_close(pVosContext);
12463
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012464 //Clean up HDD Nlink Service
12465 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012466
Manjeet Singh47ee8472016-04-11 11:57:18 +053012467 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012468 wlan_free_fwr_mem_dump_buffer();
12469 memdump_deinit();
12470
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012471#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012472 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012473 {
12474 wlan_logging_sock_deactivate_svc();
12475 }
12476#endif
12477
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012478#ifdef WLAN_KD_READY_NOTIFIER
12479 nl_srv_exit(pHddCtx->ptt_pid);
12480#else
12481 nl_srv_exit();
12482#endif /* WLAN_KD_READY_NOTIFIER */
12483
Abhishek Singh00b71972016-01-07 10:51:04 +053012484#ifdef WLAN_FEATURE_RMC
12485 hdd_close_cesium_nl_sock();
12486#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012487
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 hdd_close_all_adapters( pHddCtx );
12489
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012490 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012491 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012492 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012493
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012494free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 /* free the power on lock from platform driver */
12496 if (free_riva_power_on_lock("wlan"))
12497 {
12498 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12499 __func__);
12500 }
12501
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012502 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12503 wlan_hdd_free_cache_channels(pHddCtx);
12504
c_hpothu78c7b602014-05-17 17:35:49 +053012505 //Free up dynamically allocated members inside HDD Adapter
12506 if (pHddCtx->cfg_ini)
12507 {
12508 kfree(pHddCtx->cfg_ini);
12509 pHddCtx->cfg_ini= NULL;
12510 }
12511
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012512 hdd_request_manager_deinit();
12513
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012514 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012515 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012516 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12517 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012518 {
12519 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012520 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012521 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 if (hdd_is_ssr_required())
12524 {
12525 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012526 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 msleep(5000);
12528 }
12529 hdd_set_ssr_required (VOS_FALSE);
12530}
12531
12532
12533/**---------------------------------------------------------------------------
12534
12535 \brief hdd_update_config_from_nv() - Function to update the contents of
12536 the running configuration with parameters taken from NV storage
12537
12538 \param - pHddCtx - Pointer to the HDD global context
12539
12540 \return - VOS_STATUS_SUCCESS if successful
12541
12542 --------------------------------------------------------------------------*/
12543static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12544{
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 v_BOOL_t itemIsValid = VOS_FALSE;
12546 VOS_STATUS status;
12547 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12548 v_U8_t macLoop;
12549
12550 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12551 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12552 if(status != VOS_STATUS_SUCCESS)
12553 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012554 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 return VOS_STATUS_E_FAILURE;
12556 }
12557
12558 if (itemIsValid == VOS_TRUE)
12559 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12562 VOS_MAX_CONCURRENCY_PERSONA);
12563 if(status != VOS_STATUS_SUCCESS)
12564 {
12565 /* Get MAC from NV fail, not update CFG info
12566 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012567 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 return VOS_STATUS_E_FAILURE;
12569 }
12570
12571 /* If first MAC is not valid, treat all others are not valid
12572 * Then all MACs will be got from ini file */
12573 if(vos_is_macaddr_zero(&macFromNV[0]))
12574 {
12575 /* MAC address in NV file is not configured yet */
12576 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12577 return VOS_STATUS_E_INVAL;
12578 }
12579
12580 /* Get MAC address from NV, update CFG info */
12581 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12582 {
12583 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12584 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012585 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 /* This MAC is not valid, skip it
12587 * This MAC will be got from ini file */
12588 }
12589 else
12590 {
12591 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12592 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12593 VOS_MAC_ADDR_SIZE);
12594 }
12595 }
12596 }
12597 else
12598 {
12599 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12600 return VOS_STATUS_E_FAILURE;
12601 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012602
Jeff Johnson295189b2012-06-20 16:38:30 -070012603
12604 return VOS_STATUS_SUCCESS;
12605}
12606
12607/**---------------------------------------------------------------------------
12608
12609 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12610
12611 \param - pAdapter - Pointer to the HDD
12612
12613 \return - None
12614
12615 --------------------------------------------------------------------------*/
12616VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12617{
12618 eHalStatus halStatus;
12619 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012620 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012621
Jeff Johnson295189b2012-06-20 16:38:30 -070012622
12623 // Send ready indication to the HDD. This will kick off the MAC
12624 // into a 'running' state and should kick off an initial scan.
12625 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12626 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12627 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012628 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 "code %08d [x%08x]",__func__, halStatus, halStatus );
12630 return VOS_STATUS_E_FAILURE;
12631 }
12632
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012633 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12635 // And RIVA will crash
12636 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12637 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012638 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12639 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12640
12641
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 return VOS_STATUS_SUCCESS;
12643}
12644
Jeff Johnson295189b2012-06-20 16:38:30 -070012645/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012646void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012647{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012648
12649 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12650
Jeff Johnson295189b2012-06-20 16:38:30 -070012651}
12652
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012653void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012654{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012655
12656 vos_wake_lock_release(&wlan_wake_lock, reason);
12657
Jeff Johnson295189b2012-06-20 16:38:30 -070012658}
12659
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012660void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012661{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012662
12663 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12664 reason);
12665
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012666}
12667
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012668/**
12669 * hdd_get_feature_caps_cb() - Callback invoked from WDA
12670 * @cookie: to identify HDD request to firmware
12671 *
12672 * This function is invoked from WDA when feature capabilities response
12673 * is received from firmware.
12674 *
12675 * Return: None
12676 */
12677static void hdd_get_feature_caps_cb(void *cookie)
12678{
12679 struct hdd_request *request;
12680
12681 request = hdd_request_get(cookie);
12682 if (!request) {
12683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
12684 return;
12685 }
12686
12687 pr_info("%s: Firmware feature capabilities received\n", __func__);
12688
12689 hdd_request_complete(request);
12690 hdd_request_put(request);
12691}
12692
12693/**
12694 * hdd_get_feature_caps() - Get features supported by firmware
12695 * @hdd_ctx: Pointer to HDD context
12696 *
12697 * This function uses request manager framework to get the feature
12698 * capabilities from firmware.
12699 *
12700 * Return: None
12701 */
12702static void hdd_get_feature_caps(hdd_context_t *hdd_ctx)
12703{
12704 VOS_STATUS status;
12705 void *cookie;
12706 int ret;
12707 struct hdd_request *request;
12708 static const struct hdd_request_params params = {
12709 .priv_size = 0,
12710 .timeout_ms = WLAN_WAIT_TIME_FEATURE_CAPS,
12711 };
12712 struct sir_feature_caps_params caps_params = {0};
12713
12714 request = hdd_request_alloc(&params);
12715 if (!request) {
12716 pr_err("%s: Request allocation failure\n", __func__);
12717 return;
12718 }
12719
12720 cookie = hdd_request_cookie(request);
12721 caps_params.user_data = cookie;
12722 caps_params.feature_caps_cb = hdd_get_feature_caps_cb;
12723
12724 status = sme_featureCapsExchange(&caps_params);
12725 if (status != VOS_STATUS_SUCCESS) {
12726 pr_err("%s: Unable to get feature caps\n", __func__);
12727 goto end;
12728 }
12729
12730 /* request was sent -- wait for the response */
12731 ret = hdd_request_wait_for_response(request);
12732 if (ret) {
12733 pr_err("%s: SME timeout while retrieving feature caps\n",
12734 __func__);
12735 goto end;
12736 }
12737
12738end:
12739 hdd_request_put(request);
12740}
12741
Jeff Johnson295189b2012-06-20 16:38:30 -070012742/**---------------------------------------------------------------------------
12743
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012744 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12745 information between Host and Riva
12746
12747 This function gets reported version of FW
12748 It also finds the version of Riva headers used to compile the host
12749 It compares the above two and prints a warning if they are different
12750 It gets the SW and HW version string
12751 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12752 indicating the features they support through a bitmap
12753
12754 \param - pHddCtx - Pointer to HDD context
12755
12756 \return - void
12757
12758 --------------------------------------------------------------------------*/
12759
12760void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12761{
12762
12763 tSirVersionType versionCompiled;
12764 tSirVersionType versionReported;
12765 tSirVersionString versionString;
12766 tANI_U8 fwFeatCapsMsgSupported = 0;
12767 VOS_STATUS vstatus;
12768
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012769 memset(&versionCompiled, 0, sizeof(versionCompiled));
12770 memset(&versionReported, 0, sizeof(versionReported));
12771
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012772 /* retrieve and display WCNSS version information */
12773 do {
12774
12775 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12776 &versionCompiled);
12777 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12778 {
12779 hddLog(VOS_TRACE_LEVEL_FATAL,
12780 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012781 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012782 break;
12783 }
12784
12785 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12786 &versionReported);
12787 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12788 {
12789 hddLog(VOS_TRACE_LEVEL_FATAL,
12790 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012791 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012792 break;
12793 }
12794
12795 if ((versionCompiled.major != versionReported.major) ||
12796 (versionCompiled.minor != versionReported.minor) ||
12797 (versionCompiled.version != versionReported.version) ||
12798 (versionCompiled.revision != versionReported.revision))
12799 {
12800 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12801 "Host expected %u.%u.%u.%u\n",
12802 WLAN_MODULE_NAME,
12803 (int)versionReported.major,
12804 (int)versionReported.minor,
12805 (int)versionReported.version,
12806 (int)versionReported.revision,
12807 (int)versionCompiled.major,
12808 (int)versionCompiled.minor,
12809 (int)versionCompiled.version,
12810 (int)versionCompiled.revision);
12811 }
12812 else
12813 {
12814 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12815 WLAN_MODULE_NAME,
12816 (int)versionReported.major,
12817 (int)versionReported.minor,
12818 (int)versionReported.version,
12819 (int)versionReported.revision);
12820 }
12821
12822 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12823 versionString,
12824 sizeof(versionString));
12825 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12826 {
12827 hddLog(VOS_TRACE_LEVEL_FATAL,
12828 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012829 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012830 break;
12831 }
12832
12833 pr_info("%s: WCNSS software version %s\n",
12834 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012835 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012836
12837 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12838 versionString,
12839 sizeof(versionString));
12840 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12841 {
12842 hddLog(VOS_TRACE_LEVEL_FATAL,
12843 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012844 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012845 break;
12846 }
12847
12848 pr_info("%s: WCNSS hardware version %s\n",
12849 WLAN_MODULE_NAME, versionString);
12850
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012851 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12852 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012853 send the message only if it the riva is 1.1
12854 minor numbers for different riva branches:
12855 0 -> (1.0)Mainline Build
12856 1 -> (1.1)Mainline Build
12857 2->(1.04) Stability Build
12858 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012859 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012860 ((versionReported.minor>=1) && (versionReported.version>=1)))
12861 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12862 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012863
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012864 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012865 {
12866#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12867 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12868 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12869#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012870 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12871 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12872 {
12873 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12874 }
12875
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012876 hdd_get_feature_caps(pHddCtx);
Yathish9f22e662012-12-10 14:21:35 -080012877 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012878
12879 } while (0);
12880
12881}
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012882
Neelansh Mittaledafed22014-09-04 18:54:39 +053012883void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12884{
12885 struct sk_buff *skb;
12886 struct nlmsghdr *nlh;
12887 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012888 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012889 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012890
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012891 if (in_interrupt() || irqs_disabled() || in_atomic())
12892 flags = GFP_ATOMIC;
12893
12894 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012895
12896 if(skb == NULL) {
12897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12898 "%s: alloc_skb failed", __func__);
12899 return;
12900 }
12901
12902 nlh = (struct nlmsghdr *)skb->data;
12903 nlh->nlmsg_pid = 0; /* from kernel */
12904 nlh->nlmsg_flags = 0;
12905 nlh->nlmsg_seq = 0;
12906 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12907
12908 ani_hdr = NLMSG_DATA(nlh);
12909 ani_hdr->type = type;
12910
12911 switch(type) {
12912 case WLAN_SVC_SAP_RESTART_IND:
12913 ani_hdr->length = 0;
12914 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12915 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12916 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012917 case WLAN_SVC_WLAN_TP_IND:
12918 ani_hdr->length = len;
12919 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12920 + len));
12921 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12922 memcpy(nl_data, data, len);
12923 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12924 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012925 case WLAN_MSG_RPS_ENABLE_IND:
12926 ani_hdr->length = len;
12927 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12928 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12929 memcpy(nl_data, data, len);
12930 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12931 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012932 default:
12933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12934 "Attempt to send unknown nlink message %d", type);
12935 kfree_skb(skb);
12936 return;
12937 }
12938
12939 nl_srv_bcast(skb);
12940
12941 return;
12942}
12943
Bhargav Shahd0715912015-10-01 18:17:37 +053012944/**
12945 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12946 * @pHddCtx: Valid Global HDD context pointer
12947 * @rx_packets: Number of RX packet in perticular time
12948 *
12949 * Based on the RX packet this function calculate next value of tcp delack.
12950 * This function compare rx packet value to high and low threshold limit.
12951 *
12952 * Return: void
12953 */
12954void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12955{
12956 /* average of rx_packets and prev_rx is taken so that
12957 bus width doesnot fluctuate much */
12958 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012959 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012960
Bhargav Shahd0715912015-10-01 18:17:37 +053012961 pHddCtx->prev_rx = rx_packets;
12962 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012963 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053012964 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053012965 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053012966
12967 hdd_set_delack_value(pHddCtx, next_rx_level);
12968}
12969
12970#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12971
12972/**
12973 * hdd_tcp_delack_compute_function() - get link status
12974 * @priv: Valid Global HDD context pointer
12975 *
12976 * This function find number of RX packet during timer life span.
12977 * It request tcp delack with number of RX packet and re-configure delack timer
12978 * for tcpDelAckComputeInterval timer interval.
12979 *
12980 * Return: void
12981 */
12982void hdd_tcp_delack_compute_function(void *priv)
12983{
12984 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12985 hdd_adapter_t *pAdapter = NULL;
12986 v_U32_t rx_packets = 0;
12987 hdd_adapter_list_node_t *pAdapterNode = NULL;
12988 VOS_STATUS status = 0;
12989
12990 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12991 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12992 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12993 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12994 continue;
12995
12996 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12997 pAdapter->prev_rx_packets);
12998 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12999 }
13000
13001 hdd_request_tcp_delack(pHddCtx, rx_packets);
13002
13003 vos_timer_start(&pHddCtx->delack_timer,
13004 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13005}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013006
13007/**---------------------------------------------------------------------------
13008
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013009 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
13010
13011 \param - pHddCtx - Pointer to the hdd context
13012
13013 \return - true if hardware supports 5GHz
13014
13015 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053013016boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013017{
13018 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
13019 * then hardware support 5Ghz.
13020 */
13021 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
13022 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013023 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013024 return true;
13025 }
13026 else
13027 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013029 __func__);
13030 return false;
13031 }
13032}
13033
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013034/**---------------------------------------------------------------------------
13035
13036 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
13037 generate function
13038
13039 This is generate the random mac address for WLAN interface
13040
13041 \param - pHddCtx - Pointer to HDD context
13042 idx - Start interface index to get auto
13043 generated mac addr.
13044 mac_addr - Mac address
13045
13046 \return - 0 for success, < 0 for failure
13047
13048 --------------------------------------------------------------------------*/
13049
13050static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
13051 int idx, v_MACADDR_t mac_addr)
13052{
13053 int i;
13054 unsigned int serialno;
13055 serialno = wcnss_get_serial_number();
13056
13057 if (0 != serialno)
13058 {
13059 /* MAC address has 3 bytes of OUI so we have a maximum of 3
13060 bytes of the serial number that can be used to generate
13061 the other 3 bytes of the MAC address. Mask off all but
13062 the lower 3 bytes (this will also make sure we don't
13063 overflow in the next step) */
13064 serialno &= 0x00FFFFFF;
13065
13066 /* we need a unique address for each session */
13067 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
13068
13069 /* autogen other Mac addresses */
13070 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
13071 {
13072 /* start with the entire default address */
13073 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
13074 /* then replace the lower 3 bytes */
13075 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
13076 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
13077 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
13078
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053013079 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
13080 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
13081 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
13082 VOS_MAX_CONCURRENCY_PERSONA;
13083
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013084 serialno++;
13085 hddLog(VOS_TRACE_LEVEL_ERROR,
13086 "%s: Derived Mac Addr: "
13087 MAC_ADDRESS_STR, __func__,
13088 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
13089 }
13090
13091 }
13092 else
13093 {
13094 hddLog(LOGE, FL("Failed to Get Serial NO"));
13095 return -1;
13096 }
13097 return 0;
13098}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013099
Katya Nigame7b69a82015-04-28 15:24:06 +053013100int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13101{
13102 VOS_STATUS status;
13103 v_CONTEXT_t pVosContext= NULL;
13104 hdd_adapter_t *pAdapter= NULL;
13105
13106 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13107
13108 if (NULL == pVosContext)
13109 {
13110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13111 "%s: Trying to open VOSS without a PreOpen", __func__);
13112 VOS_ASSERT(0);
13113 return VOS_STATUS_E_FAILURE;
13114 }
13115
13116 status = vos_nv_open();
13117 if (!VOS_IS_STATUS_SUCCESS(status))
13118 {
13119 /* NV module cannot be initialized */
13120 hddLog( VOS_TRACE_LEVEL_FATAL,
13121 "%s: vos_nv_open failed", __func__);
13122 return VOS_STATUS_E_FAILURE;
13123 }
13124
13125 status = vos_init_wiphy_from_nv_bin();
13126 if (!VOS_IS_STATUS_SUCCESS(status))
13127 {
13128 /* NV module cannot be initialized */
13129 hddLog( VOS_TRACE_LEVEL_FATAL,
13130 "%s: vos_init_wiphy failed", __func__);
13131 goto err_vos_nv_close;
13132 }
13133
13134 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13135 if ( !VOS_IS_STATUS_SUCCESS( status ))
13136 {
13137 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13138 goto err_vos_nv_close;
13139 }
13140
13141 status = vos_mon_start( pVosContext );
13142 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13143 {
13144 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13145 goto err_vosclose;
13146 }
13147
13148 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013149 sme_featureCapsExchange(NULL);
Katya Nigame7b69a82015-04-28 15:24:06 +053013150 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13151
13152 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13153 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13154 if( pAdapter == NULL )
13155 {
13156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13157 goto err_close_adapter;
13158 }
13159
13160 //Initialize the nlink service
13161 if(nl_srv_init() != 0)
13162 {
13163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13164 goto err_close_adapter;
13165 }
13166 return VOS_STATUS_SUCCESS;
13167
13168err_close_adapter:
13169 hdd_close_all_adapters( pHddCtx );
13170 vos_mon_stop( pVosContext );
13171err_vosclose:
13172 status = vos_sched_close( pVosContext );
13173 if (!VOS_IS_STATUS_SUCCESS(status)) {
13174 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13175 "%s: Failed to close VOSS Scheduler", __func__);
13176 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13177 }
13178 vos_close(pVosContext );
13179
13180err_vos_nv_close:
13181 vos_nv_close();
13182
13183return status;
13184}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013185/**---------------------------------------------------------------------------
13186
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013187 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13188 completed to flush out the scan results
13189
13190 11d scan is done during driver load and is a passive scan on all
13191 channels supported by the device, 11d scans may find some APs on
13192 frequencies which are forbidden to be used in the regulatory domain
13193 the device is operating in. If these APs are notified to the supplicant
13194 it may try to connect to these APs, thus flush out all the scan results
13195 which are present in SME after 11d scan is done.
13196
13197 \return - eHalStatus
13198
13199 --------------------------------------------------------------------------*/
13200static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13201 tANI_U32 scanId, eCsrScanStatus status)
13202{
13203 ENTER();
13204
13205 sme_ScanFlushResult(halHandle, 0);
13206
13207 EXIT();
13208
13209 return eHAL_STATUS_SUCCESS;
13210}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013211/**---------------------------------------------------------------------------
13212
13213 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13214 logging is completed successfully.
13215
13216 \return - None
13217
13218 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013219void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013220{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013221 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013222
13223 if (NULL == pHddCtx)
13224 {
13225 hddLog(VOS_TRACE_LEVEL_ERROR,
13226 "%s: HDD context is NULL",__func__);
13227 return;
13228 }
13229
c_manjeecfd1efb2015-09-25 19:32:34 +053013230 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013231 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013232 {
13233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13234 pHddCtx->mgmt_frame_logging = TRUE;
13235 }
13236 else
13237 {
13238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13239 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013240 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013241 }
13242
c_manjeecfd1efb2015-09-25 19:32:34 +053013243 /*Check feature supported by FW*/
13244 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13245 {
13246 //Store fwr mem dump size given by firmware.
13247 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13248 }
13249 else
13250 {
13251 wlan_store_fwr_mem_dump_size(0);
13252 }
13253
13254
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013255}
13256/**---------------------------------------------------------------------------
13257
13258 \brief hdd_init_frame_logging - function to initialize frame logging.
13259 Currently only Mgmt Frames are logged in both TX
13260 and Rx direction and are sent to userspace
13261 application using logger thread when queried.
13262
13263 \return - None
13264
13265 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013266void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013267{
13268 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013269 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013270
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013271 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13272 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013273 {
13274 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13275 return;
13276 }
13277
c_manjeecfd1efb2015-09-25 19:32:34 +053013278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013279 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13280 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013281 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13282 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013283
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013284 if (pHddCtx->cfg_ini->enableFWLogging ||
13285 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013286 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013287 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013288 }
13289
Sushant Kaushik46804902015-07-08 14:46:03 +053013290 if (pHddCtx->cfg_ini->enableMgmtLogging)
13291 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013292 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013293 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013294 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13295 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013296 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013297 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013298 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13299 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13300 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013301 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013302 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013303 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013304 {
13305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13306 return;
13307 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013308 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13309 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13310 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13311 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013312 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013313
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013314 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013315
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013316 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013317 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013318 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013319 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013320 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13321 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013322
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013323 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013324
13325 if (eHAL_STATUS_SUCCESS != halStatus)
13326 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013327 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13328 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013329 }
13330
13331 return;
13332}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013333
Bhargav shah23c94942015-10-13 12:48:35 +053013334static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13335{
13336 hdd_adapter_t *adapter;
13337 hdd_adapter_list_node_t *adapter_node, *next;
13338 VOS_STATUS status = VOS_STATUS_SUCCESS;
13339 struct wlan_rps_data rps_data;
13340 int count;
13341
13342 if(!hdd_ctxt->cfg_ini->rps_mask)
13343 {
13344 return;
13345 }
13346
13347 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13348 {
13349 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13350 }
13351
13352 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13353
13354 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13355 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13356 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13357
13358 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13359
13360 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13361 {
13362 adapter = adapter_node->pAdapter;
13363 if (NULL != adapter) {
13364 strlcpy(rps_data.ifname, adapter->dev->name,
13365 sizeof(rps_data.ifname));
13366 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13367 (void *)&rps_data,sizeof(rps_data));
13368 }
13369 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13370 adapter_node = next;
13371 }
13372}
13373
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013374void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13375{
13376 scan_context_t *scan_ctx =
13377 container_of(work, scan_context_t, scan_work.work);
13378
13379 if (NULL == scan_ctx)
13380 {
13381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13382 FL("scan_ctx is NULL"));
13383 return;
13384 }
13385
13386 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13387 return;
13388
13389 scan_ctx->attempt++;
13390
13391 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13392#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13393 scan_ctx->dev,
13394#endif
13395 scan_ctx->scan_request);
13396}
13397
13398int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13399 struct wiphy *wiphy,
13400#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13401 struct net_device *dev,
13402#endif
13403 struct cfg80211_scan_request *request)
13404{
13405 scan_context_t *scan_ctx;
13406
13407 ENTER();
13408 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13409 {
13410 return -1;
13411 }
13412
13413 scan_ctx = &pHddCtx->scan_ctxt;
13414
13415 scan_ctx->wiphy = wiphy;
13416#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13417 scan_ctx->dev = dev;
13418#endif
13419
13420 scan_ctx->scan_request = request;
13421
13422 EXIT();
13423 return 0;
13424}
13425
13426void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13427 struct wiphy *wiphy,
13428#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13429 struct net_device *dev,
13430#endif
13431 struct cfg80211_scan_request *request,
13432 unsigned long delay)
13433{
13434 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13435 {
13436#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13437 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13438#else
13439 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13440#endif
13441 pHddCtx->scan_ctxt.attempt = 0;
13442 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13443 }
13444 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13445}
13446
13447void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13448{
13449 scan_ctx->magic = 0;
13450 scan_ctx->attempt = 0;
13451 scan_ctx->reject = 0;
13452 scan_ctx->scan_request = NULL;
13453
13454 return;
13455}
13456
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013457/**---------------------------------------------------------------------------
13458
Jeff Johnson295189b2012-06-20 16:38:30 -070013459 \brief hdd_wlan_startup() - HDD init function
13460
13461 This is the driver startup code executed once a WLAN device has been detected
13462
13463 \param - dev - Pointer to the underlying device
13464
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013465 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013466
13467 --------------------------------------------------------------------------*/
13468
13469int hdd_wlan_startup(struct device *dev )
13470{
13471 VOS_STATUS status;
13472 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013473 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013474 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 hdd_context_t *pHddCtx = NULL;
13476 v_CONTEXT_t pVosContext= NULL;
13477#ifdef WLAN_BTAMP_FEATURE
13478 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13479 WLANBAP_ConfigType btAmpConfig;
13480 hdd_config_t *pConfig;
13481#endif
13482 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013483 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013484 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013485
13486 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 /*
13488 * cfg80211: wiphy allocation
13489 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013490 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013491
13492 if(wiphy == NULL)
13493 {
13494 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013495 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 pHddCtx = wiphy_priv(wiphy);
13498
Jeff Johnson295189b2012-06-20 16:38:30 -070013499 //Initialize the adapter context to zeros.
13500 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13501
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013503 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013504 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013505
13506 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13507
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013508 /* register for riva power on lock to platform driver
13509 * Locking power early to ensure FW doesn't reset by kernel while
13510 * host driver is busy initializing itself */
13511 if (req_riva_power_on_lock("wlan"))
13512 {
13513 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13514 __func__);
13515 goto err_free_hdd_context;
13516 }
13517
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 /*Get vos context here bcoz vos_open requires it*/
13519 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13520
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013521 if(pVosContext == NULL)
13522 {
13523 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13524 goto err_free_hdd_context;
13525 }
13526
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 //Save the Global VOSS context in adapter context for future.
13528 pHddCtx->pvosContext = pVosContext;
13529
13530 //Save the adapter context in global context for future.
13531 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13532
Jeff Johnson295189b2012-06-20 16:38:30 -070013533 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013534 pHddCtx->last_scan_reject_session_id = 0xFF;
13535 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013536 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013537 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013538
13539 init_completion(&pHddCtx->full_pwr_comp_var);
13540 init_completion(&pHddCtx->standby_comp_var);
13541 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013542 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013543 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013544 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013545 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013546 init_completion(&pHddCtx->mc_sus_event_var);
13547 init_completion(&pHddCtx->tx_sus_event_var);
13548 init_completion(&pHddCtx->rx_sus_event_var);
13549
Amar Singhala49cbc52013-10-08 18:37:44 -070013550
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013551 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013552 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013553
Amar Singhala49cbc52013-10-08 18:37:44 -070013554#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013555 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013556#else
13557 init_completion(&pHddCtx->driver_crda_req);
13558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013559
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013560#ifdef WLAN_FEATURE_EXTSCAN
13561 init_completion(&pHddCtx->ext_scan_context.response_event);
13562#endif /* WLAN_FEATURE_EXTSCAN */
13563
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013564 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013565 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013566
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13568
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013569 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13570 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013571 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013572 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13573 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013574
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013575#ifdef FEATURE_WLAN_TDLS
13576 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13577 * invoked by other instances also) to protect the concurrent
13578 * access for the Adapters by TDLS module.
13579 */
13580 mutex_init(&pHddCtx->tdls_lock);
13581#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013582 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013583 mutex_init(&pHddCtx->wmmLock);
13584
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013585 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013586 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013587
Agarwal Ashish1f422872014-07-22 00:11:55 +053013588 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 // Load all config first as TL config is needed during vos_open
13590 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13591 if(pHddCtx->cfg_ini == NULL)
13592 {
13593 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13594 goto err_free_hdd_context;
13595 }
13596
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013597 hdd_request_manager_init();
13598
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13600
13601 // Read and parse the qcom_cfg.ini file
13602 status = hdd_parse_config_ini( pHddCtx );
13603 if ( VOS_STATUS_SUCCESS != status )
13604 {
13605 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13606 __func__, WLAN_INI_FILE);
13607 goto err_config;
13608 }
Arif Hussaind5218912013-12-05 01:10:55 -080013609#ifdef MEMORY_DEBUG
13610 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13611 vos_mem_init();
13612
13613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13614 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013617 /* INI has been read, initialise the configuredMcastBcastFilter with
13618 * INI value as this will serve as the default value
13619 */
13620 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13621 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13622 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013623
13624 if (false == hdd_is_5g_supported(pHddCtx))
13625 {
13626 //5Ghz is not supported.
13627 if (1 != pHddCtx->cfg_ini->nBandCapability)
13628 {
13629 hddLog(VOS_TRACE_LEVEL_INFO,
13630 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13631 pHddCtx->cfg_ini->nBandCapability = 1;
13632 }
13633 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013634
13635 /* If SNR Monitoring is enabled, FW has to parse all beacons
13636 * for calcaluting and storing the average SNR, so set Nth beacon
13637 * filter to 1 to enable FW to parse all the beaocons
13638 */
13639 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13640 {
13641 /* The log level is deliberately set to WARN as overriding
13642 * nthBeaconFilter to 1 will increase power cosumption and this
13643 * might just prove helpful to detect the power issue.
13644 */
13645 hddLog(VOS_TRACE_LEVEL_WARN,
13646 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13647 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13648 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013650 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013652 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013654 hddLog(VOS_TRACE_LEVEL_FATAL,
13655 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13656 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013658
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013659 // Update VOS trace levels based upon the cfg.ini
13660 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13661 pHddCtx->cfg_ini->vosTraceEnableBAP);
13662 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13663 pHddCtx->cfg_ini->vosTraceEnableTL);
13664 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13665 pHddCtx->cfg_ini->vosTraceEnableWDI);
13666 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13667 pHddCtx->cfg_ini->vosTraceEnableHDD);
13668 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13669 pHddCtx->cfg_ini->vosTraceEnableSME);
13670 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13671 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013672 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13673 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013674 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13675 pHddCtx->cfg_ini->vosTraceEnableWDA);
13676 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13677 pHddCtx->cfg_ini->vosTraceEnableSYS);
13678 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13679 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013680 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13681 pHddCtx->cfg_ini->vosTraceEnableSAP);
13682 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13683 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013684
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 // Update WDI trace levels based upon the cfg.ini
13686 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13687 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13688 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13689 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13690 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13691 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13692 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13693 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013694
Jeff Johnson88ba7742013-02-27 14:36:02 -080013695 if (VOS_FTM_MODE == hdd_get_conparam())
13696 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013697 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13698 {
13699 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13700 goto err_free_hdd_context;
13701 }
13702 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013703 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013704 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013706 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013707
Katya Nigame7b69a82015-04-28 15:24:06 +053013708 if( VOS_MONITOR_MODE == hdd_get_conparam())
13709 {
13710 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13711 {
13712 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13713 goto err_free_hdd_context;
13714 }
13715 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13716 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13717 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13718 return VOS_STATUS_SUCCESS;
13719 }
13720
Jeff Johnson88ba7742013-02-27 14:36:02 -080013721 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013722 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13723 {
13724 status = vos_watchdog_open(pVosContext,
13725 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13726
13727 if(!VOS_IS_STATUS_SUCCESS( status ))
13728 {
13729 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013730 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 }
13732 }
13733
13734 pHddCtx->isLogpInProgress = FALSE;
13735 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13736
Amar Singhala49cbc52013-10-08 18:37:44 -070013737#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013738 /* initialize the NV module. This is required so that
13739 we can initialize the channel information in wiphy
13740 from the NV.bin data. The channel information in
13741 wiphy needs to be initialized before wiphy registration */
13742
13743 status = vos_nv_open();
13744 if (!VOS_IS_STATUS_SUCCESS(status))
13745 {
13746 /* NV module cannot be initialized */
13747 hddLog( VOS_TRACE_LEVEL_FATAL,
13748 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013749 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013750 }
13751
13752 status = vos_init_wiphy_from_nv_bin();
13753 if (!VOS_IS_STATUS_SUCCESS(status))
13754 {
13755 /* NV module cannot be initialized */
13756 hddLog( VOS_TRACE_LEVEL_FATAL,
13757 "%s: vos_init_wiphy failed", __func__);
13758 goto err_vos_nv_close;
13759 }
13760
Amar Singhala49cbc52013-10-08 18:37:44 -070013761#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013762 //Initialize the nlink service
13763 if(nl_srv_init() != 0)
13764 {
13765 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13766 goto err_vos_nv_close;
13767 }
13768
13769#ifdef WLAN_KD_READY_NOTIFIER
13770 pHddCtx->kd_nl_init = 1;
13771#endif /* WLAN_KD_READY_NOTIFIER */
13772
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013773 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013774 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 if ( !VOS_IS_STATUS_SUCCESS( status ))
13776 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013777 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013778 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 }
13780
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13782
13783 if ( NULL == pHddCtx->hHal )
13784 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013785 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 goto err_vosclose;
13787 }
13788
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013789 status = vos_preStart( pHddCtx->pvosContext );
13790 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13791 {
13792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013793 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013794 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013795
Arif Hussaineaf68602013-12-30 23:10:44 -080013796 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13797 {
13798 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13800 __func__, enable_dfs_chan_scan);
13801 }
13802 if (0 == enable_11d || 1 == enable_11d)
13803 {
13804 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13806 __func__, enable_11d);
13807 }
13808
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013809 /* Note that the vos_preStart() sequence triggers the cfg download.
13810 The cfg download must occur before we update the SME config
13811 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013812 status = hdd_set_sme_config( pHddCtx );
13813
13814 if ( VOS_STATUS_SUCCESS != status )
13815 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013816 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013817 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013818 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013819
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 /* In the integrated architecture we update the configuration from
13821 the INI file and from NV before vOSS has been started so that
13822 the final contents are available to send down to the cCPU */
13823
13824 // Apply the cfg.ini to cfg.dat
13825 if (FALSE == hdd_update_config_dat(pHddCtx))
13826 {
13827 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013828 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013829 }
13830
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013831 // Get mac addr from platform driver
13832 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13833
13834 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013835 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013836 /* Store the mac addr for first interface */
13837 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13838
13839 hddLog(VOS_TRACE_LEVEL_ERROR,
13840 "%s: WLAN Mac Addr: "
13841 MAC_ADDRESS_STR, __func__,
13842 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13843
13844 /* Here, passing Arg2 as 1 because we do not want to change the
13845 last 3 bytes (means non OUI bytes) of first interface mac
13846 addr.
13847 */
13848 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13849 {
13850 hddLog(VOS_TRACE_LEVEL_ERROR,
13851 "%s: Failed to generate wlan interface mac addr "
13852 "using MAC from ini file ", __func__);
13853 }
13854 }
13855 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13856 {
13857 // Apply the NV to cfg.dat
13858 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013859#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13860 /* There was not a valid set of MAC Addresses in NV. See if the
13861 default addresses were modified by the cfg.ini settings. If so,
13862 we'll use them, but if not, we'll autogenerate a set of MAC
13863 addresses based upon the device serial number */
13864
13865 static const v_MACADDR_t default_address =
13866 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013867
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013868 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13869 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 {
13871 /* cfg.ini has the default address, invoke autogen logic */
13872
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013873 /* Here, passing Arg2 as 0 because we want to change the
13874 last 3 bytes (means non OUI bytes) of all the interfaces
13875 mac addr.
13876 */
13877 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13878 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013880 hddLog(VOS_TRACE_LEVEL_ERROR,
13881 "%s: Failed to generate wlan interface mac addr "
13882 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13883 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 }
13886 else
13887#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13888 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013889 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 "%s: Invalid MAC address in NV, using MAC from ini file "
13891 MAC_ADDRESS_STR, __func__,
13892 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13893 }
13894 }
13895 {
13896 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013897
13898 /* Set the MAC Address Currently this is used by HAL to
13899 * add self sta. Remove this once self sta is added as
13900 * part of session open.
13901 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13903 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13904 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013905
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 if (!HAL_STATUS_SUCCESS( halStatus ))
13907 {
13908 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13909 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013910 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 }
13912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013913
13914 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13915 Note: Firmware image will be read and downloaded inside vos_start API */
13916 status = vos_start( pHddCtx->pvosContext );
13917 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13918 {
13919 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013920 if (isSsrPanicOnFailure())
13921 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013922 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 }
13924
Leo Chang6cec3e22014-01-21 15:33:49 -080013925#ifdef FEATURE_WLAN_CH_AVOID
13926 /* Plug in avoid channel notification callback
13927 * This should happen before ADD_SELF_STA
13928 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013929
13930 /* check the Channel Avoidance is enabled */
13931 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13932 {
13933 sme_AddChAvoidCallback(pHddCtx->hHal,
13934 hdd_hostapd_ch_avoid_cb);
13935 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013936#endif /* FEATURE_WLAN_CH_AVOID */
13937
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013938 /* Exchange capability info between Host and FW and also get versioning info from FW */
13939 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013940
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013941#ifdef CONFIG_ENABLE_LINUX_REG
13942 status = wlan_hdd_init_channels(pHddCtx);
13943 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13944 {
13945 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13946 __func__);
13947 goto err_vosstop;
13948 }
13949#endif
13950
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 status = hdd_post_voss_start_config( pHddCtx );
13952 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13953 {
13954 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13955 __func__);
13956 goto err_vosstop;
13957 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013958
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053013959 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
13960
Amar Singhala49cbc52013-10-08 18:37:44 -070013961#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013962 wlan_hdd_cfg80211_update_reg_info( wiphy );
13963
13964 /* registration of wiphy dev with cfg80211 */
13965 if (0 > wlan_hdd_cfg80211_register(wiphy))
13966 {
13967 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13968 goto err_vosstop;
13969 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013971
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013972#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013973 /* registration of wiphy dev with cfg80211 */
13974 if (0 > wlan_hdd_cfg80211_register(wiphy))
13975 {
13976 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13977 goto err_vosstop;
13978 }
13979
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013980 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013981 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13982 {
13983 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13984 __func__);
13985 goto err_unregister_wiphy;
13986 }
13987#endif
13988
c_hpothu4a298be2014-12-22 21:12:51 +053013989 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13990
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013991#ifdef SAP_AUTH_OFFLOAD
13992 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
13993 {
13994 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
13995 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
13996 }
13997#endif
13998
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 if (VOS_STA_SAP_MODE == hdd_get_conparam())
14000 {
14001 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
14002 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14003 }
14004 else
14005 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
14007 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14008 if (pAdapter != NULL)
14009 {
Katya Nigama7d81d72014-11-12 12:44:34 +053014010 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014012 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
14013 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
14014 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070014015
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014016 /* Generate the P2P Device Address. This consists of the device's
14017 * primary MAC address with the locally administered bit set.
14018 */
14019 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070014020 }
14021 else
14022 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014023 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
14024 if (p2p_dev_addr != NULL)
14025 {
14026 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
14027 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
14028 }
14029 else
14030 {
14031 hddLog(VOS_TRACE_LEVEL_FATAL,
14032 "%s: Failed to allocate mac_address for p2p_device",
14033 __func__);
14034 goto err_close_adapter;
14035 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014036 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014037
14038 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
14039 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
14040 if ( NULL == pP2pAdapter )
14041 {
14042 hddLog(VOS_TRACE_LEVEL_FATAL,
14043 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014044 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014045 goto err_close_adapter;
14046 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014047 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014049
14050 if( pAdapter == NULL )
14051 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14053 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014055
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053014056 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
14057 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053014058 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
14059 pHddCtx->cfg_ini->enabledefaultSAP,
14060 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
14061 if (!softapAdapter) {
14062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14063 goto err_close_adapter;
14064 }
14065 }
14066
Arif Hussain66559122013-11-21 10:11:40 -080014067 if (country_code)
14068 {
14069 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080014070 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080014071 hdd_checkandupdate_dfssetting(pAdapter, country_code);
14072#ifndef CONFIG_ENABLE_LINUX_REG
14073 hdd_checkandupdate_phymode(pAdapter, country_code);
14074#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080014075 ret = sme_ChangeCountryCode(pHddCtx->hHal,
14076 (void *)(tSmeChangeCountryCallback)
14077 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080014078 country_code,
14079 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053014080 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080014081 if (eHAL_STATUS_SUCCESS == ret)
14082 {
Arif Hussaincb607082013-12-20 11:57:42 -080014083 ret = wait_for_completion_interruptible_timeout(
14084 &pAdapter->change_country_code,
14085 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
14086
14087 if (0 >= ret)
14088 {
14089 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14090 "%s: SME while setting country code timed out", __func__);
14091 }
Arif Hussain66559122013-11-21 10:11:40 -080014092 }
14093 else
14094 {
Arif Hussaincb607082013-12-20 11:57:42 -080014095 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14096 "%s: SME Change Country code from module param fail ret=%d",
14097 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080014098 }
14099 }
14100
Jeff Johnson295189b2012-06-20 16:38:30 -070014101#ifdef WLAN_BTAMP_FEATURE
14102 vStatus = WLANBAP_Open(pVosContext);
14103 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14104 {
14105 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14106 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014107 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 }
14109
14110 vStatus = BSL_Init(pVosContext);
14111 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14112 {
14113 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14114 "%s: Failed to Init BSL",__func__);
14115 goto err_bap_close;
14116 }
14117 vStatus = WLANBAP_Start(pVosContext);
14118 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14119 {
14120 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14121 "%s: Failed to start TL",__func__);
14122 goto err_bap_close;
14123 }
14124
14125 pConfig = pHddCtx->cfg_ini;
14126 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14127 status = WLANBAP_SetConfig(&btAmpConfig);
14128
14129#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014130
Mihir Shete9c238772014-10-15 14:35:16 +053014131 /*
14132 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14133 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14134 * which is greater than 0xf. So the below check is safe to make
14135 * sure that there is no entry for UapsdMask in the ini
14136 */
14137 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14138 {
14139 if(IS_DYNAMIC_WMM_PS_ENABLED)
14140 {
14141 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14142 __func__);
14143 pHddCtx->cfg_ini->UapsdMask =
14144 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14145 }
14146 else
14147 {
14148 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14149 __func__);
14150 pHddCtx->cfg_ini->UapsdMask =
14151 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14152 }
14153 }
14154
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014155#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14156 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14157 {
14158 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14159 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14160 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14161 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14162 }
14163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014164
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014165 wlan_hdd_tdls_init(pHddCtx);
14166
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014167 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14168
14169 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14170 wlan_hdd_schedule_defer_scan);
14171
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014172 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14173
Jeff Johnson295189b2012-06-20 16:38:30 -070014174 /* Register with platform driver as client for Suspend/Resume */
14175 status = hddRegisterPmOps(pHddCtx);
14176 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14177 {
14178 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14179#ifdef WLAN_BTAMP_FEATURE
14180 goto err_bap_stop;
14181#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014182 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014183#endif //WLAN_BTAMP_FEATURE
14184 }
14185
Yue Ma0d4891e2013-08-06 17:01:45 -070014186 /* Open debugfs interface */
14187 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14188 {
14189 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14190 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014191 }
14192
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 /* Register TM level change handler function to the platform */
14194 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14195 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14196 {
14197 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14198 goto err_unregister_pmops;
14199 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014200
Jeff Johnson295189b2012-06-20 16:38:30 -070014201 // register net device notifier for device change notification
14202 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14203
14204 if(ret < 0)
14205 {
14206 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014207 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014208 }
14209
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 //Initialize the BTC service
14211 if(btc_activate_service(pHddCtx) != 0)
14212 {
14213 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014214 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014215 }
14216
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014217#ifdef FEATURE_OEM_DATA_SUPPORT
14218 //Initialize the OEM service
14219 if (oem_activate_service(pHddCtx) != 0)
14220 {
14221 hddLog(VOS_TRACE_LEVEL_FATAL,
14222 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014223 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014224 }
14225#endif
14226
Jeff Johnson295189b2012-06-20 16:38:30 -070014227#ifdef PTT_SOCK_SVC_ENABLE
14228 //Initialize the PTT service
14229 if(ptt_sock_activate_svc(pHddCtx) != 0)
14230 {
14231 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014232 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014233 }
14234#endif
14235
Abhishek Singh00b71972016-01-07 10:51:04 +053014236#ifdef WLAN_FEATURE_RMC
14237 if (hdd_open_cesium_nl_sock() < 0)
14238 {
14239 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014240 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014241 }
14242#endif
14243
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014244#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14245 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14246 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014247 if(wlan_logging_sock_activate_svc(
14248 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014249 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14250 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14251 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014252 {
14253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14254 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014255 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014256 }
14257 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14258 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014259 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14260 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014261 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14262 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014263 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014264
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014265 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14266 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014267 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014268 pHddCtx->cfg_ini->enableContFWLogging ||
14269 pHddCtx->cfg_ini->enableFwrMemDump )
14270 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014271 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014272 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014273 }
14274 else
14275 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014277 }
14278
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014279#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014280
Sushant Kaushik215778f2015-05-21 14:05:36 +053014281 if (vos_is_multicast_logging())
14282 wlan_logging_set_log_level();
14283
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 hdd_register_mcast_bcast_filter(pHddCtx);
Bala Venkateshe65810a2019-02-18 20:32:36 +053014285
14286 /* Action frame registered in one adapter which will
14287 * applicable to all interfaces
14288 */
14289 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014290
14291 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014292 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014293
Jeff Johnsone7245742012-09-05 17:12:55 -070014294#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14295 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014296 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014297 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014298
Jeff Johnsone7245742012-09-05 17:12:55 -070014299#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014300 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014301 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014302 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014303
Jeff Johnsone7245742012-09-05 17:12:55 -070014304
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014305 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14306 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014307
Katya Nigam5c306ea2014-06-19 15:39:54 +053014308 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014309 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014310 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014311
14312#ifdef FEATURE_WLAN_SCAN_PNO
14313 /*SME must send channel update configuration to RIVA*/
14314 sme_UpdateChannelConfig(pHddCtx->hHal);
14315#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014316 /* Send the update default channel list to the FW*/
14317 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014318
14319 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014320 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14321 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014322 sme_SetDefDot11Mode(pHddCtx->hHal);
14323
Abhishek Singha306a442013-11-07 18:39:01 +053014324#ifndef CONFIG_ENABLE_LINUX_REG
14325 /*updating wiphy so that regulatory user hints can be processed*/
14326 if (wiphy)
14327 {
14328 regulatory_hint(wiphy, "00");
14329 }
14330#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014331 // Initialize the restart logic
14332 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014333
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014334 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14335 vos_wdthread_init_timer_work(vos_process_wd_timer);
14336 /* Initialize the timer to detect thread stuck issues */
14337 vos_thread_stuck_timer_init(
14338 &((VosContextType*)pVosContext)->vosWatchdog);
14339 }
14340
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014341 //Register the traffic monitor timer now
14342 if ( pHddCtx->cfg_ini->dynSplitscan)
14343 {
14344 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14345 VOS_TIMER_TYPE_SW,
14346 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14347 (void *)pHddCtx);
14348 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014349 wlan_hdd_cfg80211_nan_init(pHddCtx);
14350
Bhargav Shahd0715912015-10-01 18:17:37 +053014351 mutex_init(&pHddCtx->cur_rx_level_lock);
14352 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14353 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014354 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14355 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014356
Dino Mycle6fb96c12014-06-10 11:52:40 +053014357#ifdef WLAN_FEATURE_EXTSCAN
14358 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14359 wlan_hdd_cfg80211_extscan_callback,
14360 pHddCtx);
14361#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014362
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014363#ifdef FEATURE_OEM_DATA_SUPPORT
14364 sme_OemDataRegisterCallback(pHddCtx->hHal,
14365 wlan_hdd_cfg80211_oemdata_callback,
14366 pHddCtx);
14367#endif /* FEATURE_OEM_DATA_SUPPORT */
14368
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014369 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014370#ifdef WLAN_NS_OFFLOAD
14371 // Register IPv6 notifier to notify if any change in IP
14372 // So that we can reconfigure the offload parameters
14373 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14374 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14375 if (ret)
14376 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014378 }
14379 else
14380 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014382 }
14383#endif
14384
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014385 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14386
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014387 // Register IPv4 notifier to notify if any change in IP
14388 // So that we can reconfigure the offload parameters
14389 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14390 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14391 if (ret)
14392 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014394 }
14395 else
14396 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014397 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014398 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014399 /*Fw mem dump procfs initialization*/
14400 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014401 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014402
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014403 pHddCtx->is_ap_mode_wow_supported =
14404 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014405
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014406 pHddCtx->is_fatal_event_log_sup =
14407 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14408 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14409 pHddCtx->is_fatal_event_log_sup);
14410
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014411 hdd_assoc_registerFwdEapolCB(pVosContext);
14412
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014413 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 goto success;
14415
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014416err_open_cesium_nl_sock:
14417#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14418 hdd_close_cesium_nl_sock();
14419#endif
14420
14421err_ptt_sock_activate_svc:
14422#ifdef PTT_SOCK_SVC_ENABLE
14423 ptt_sock_deactivate_svc(pHddCtx);
14424#endif
14425
14426err_oem_activate_service:
14427#ifdef FEATURE_OEM_DATA_SUPPORT
14428 oem_deactivate_service();
14429#endif
14430
14431err_btc_activate_service:
14432 btc_deactivate_service();
14433
Jeff Johnson295189b2012-06-20 16:38:30 -070014434err_reg_netdev:
14435 unregister_netdevice_notifier(&hdd_netdev_notifier);
14436
Jeff Johnson295189b2012-06-20 16:38:30 -070014437err_unregister_pmops:
14438 hddDevTmUnregisterNotifyCallback(pHddCtx);
14439 hddDeregisterPmOps(pHddCtx);
14440
Yue Ma0d4891e2013-08-06 17:01:45 -070014441 hdd_debugfs_exit(pHddCtx);
14442
Jeff Johnson295189b2012-06-20 16:38:30 -070014443#ifdef WLAN_BTAMP_FEATURE
14444err_bap_stop:
14445 WLANBAP_Stop(pVosContext);
14446#endif
14447
14448#ifdef WLAN_BTAMP_FEATURE
14449err_bap_close:
14450 WLANBAP_Close(pVosContext);
14451#endif
14452
Jeff Johnson295189b2012-06-20 16:38:30 -070014453err_close_adapter:
14454 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014455#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014456err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014457#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014458 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014459 hdd_wlan_free_wiphy_channels(wiphy);
14460
Jeff Johnson295189b2012-06-20 16:38:30 -070014461err_vosstop:
14462 vos_stop(pVosContext);
14463
Amar Singhala49cbc52013-10-08 18:37:44 -070014464err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014465 status = vos_sched_close( pVosContext );
14466 if (!VOS_IS_STATUS_SUCCESS(status)) {
14467 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14468 "%s: Failed to close VOSS Scheduler", __func__);
14469 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14470 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014471 vos_close(pVosContext );
14472
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014473err_nl_srv:
14474#ifdef WLAN_KD_READY_NOTIFIER
14475 nl_srv_exit(pHddCtx->ptt_pid);
14476#else
14477 nl_srv_exit();
14478#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014479err_vos_nv_close:
14480
c_hpothue6a36282014-03-19 12:27:38 +053014481#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014482 vos_nv_close();
14483
c_hpothu70f8d812014-03-22 22:59:23 +053014484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014485
14486err_wdclose:
14487 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14488 vos_watchdog_close(pVosContext);
14489
Jeff Johnson295189b2012-06-20 16:38:30 -070014490err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014491 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 kfree(pHddCtx->cfg_ini);
14493 pHddCtx->cfg_ini= NULL;
14494
14495err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014496 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014497 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 wiphy_free(wiphy) ;
14499 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 VOS_BUG(1);
14501
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014502 if (hdd_is_ssr_required())
14503 {
14504 /* WDI timeout had happened during load, so SSR is needed here */
14505 subsystem_restart("wcnss");
14506 msleep(5000);
14507 }
14508 hdd_set_ssr_required (VOS_FALSE);
14509
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014510 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014511
14512success:
14513 EXIT();
14514 return 0;
14515}
14516
14517/**---------------------------------------------------------------------------
14518
Jeff Johnson32d95a32012-09-10 13:15:23 -070014519 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014520
Jeff Johnson32d95a32012-09-10 13:15:23 -070014521 This is the driver entry point - called in different timeline depending
14522 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014523
14524 \param - None
14525
14526 \return - 0 for success, non zero for failure
14527
14528 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014529static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014530{
14531 VOS_STATUS status;
14532 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 struct device *dev = NULL;
14534 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014535#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14536 int max_retries = 0;
14537#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014538#ifdef HAVE_CBC_DONE
14539 int max_cbc_retries = 0;
14540#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014541
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014542#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14543 wlan_logging_sock_init_svc();
14544#endif
14545
Jeff Johnson295189b2012-06-20 16:38:30 -070014546 ENTER();
14547
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014548 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014549
14550 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14551 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14552
Jeff Johnson295189b2012-06-20 16:38:30 -070014553#ifdef ANI_BUS_TYPE_PCI
14554
14555 dev = wcnss_wlan_get_device();
14556
14557#endif // ANI_BUS_TYPE_PCI
14558
14559#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014560
14561#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14562 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014563 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014564 msleep(1000);
14565 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014566
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014567 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014568 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014569 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014570#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14571 wlan_logging_sock_deinit_svc();
14572#endif
14573
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014574 return -ENODEV;
14575 }
14576#endif
14577
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014578#ifdef HAVE_CBC_DONE
14579 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14580 msleep(1000);
14581 }
14582 if (max_cbc_retries >= 10) {
14583 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14584 }
14585#endif
14586
Jeff Johnson295189b2012-06-20 16:38:30 -070014587 dev = wcnss_wlan_get_device();
14588#endif // ANI_BUS_TYPE_PLATFORM
14589
14590
14591 do {
14592 if (NULL == dev) {
14593 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14594 ret_status = -1;
14595 break;
14596 }
14597
Jeff Johnson295189b2012-06-20 16:38:30 -070014598#ifdef TIMER_MANAGER
14599 vos_timer_manager_init();
14600#endif
14601
14602 /* Preopen VOSS so that it is ready to start at least SAL */
14603 status = vos_preOpen(&pVosContext);
14604
14605 if (!VOS_IS_STATUS_SUCCESS(status))
14606 {
14607 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14608 ret_status = -1;
14609 break;
14610 }
14611
Sushant Kaushik02beb352015-06-04 15:15:01 +053014612 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014613 hdd_register_debug_callback();
14614
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014615#ifndef MODULE
14616 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14617 */
14618 hdd_set_conparam((v_UINT_t)con_mode);
14619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014620
14621 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014622 if (hdd_wlan_startup(dev))
14623 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014625 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 vos_preClose( &pVosContext );
14627 ret_status = -1;
14628 break;
14629 }
14630
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 } while (0);
14632
14633 if (0 != ret_status)
14634 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014635#ifdef TIMER_MANAGER
14636 vos_timer_exit();
14637#endif
14638#ifdef MEMORY_DEBUG
14639 vos_mem_exit();
14640#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014641 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014642#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14643 wlan_logging_sock_deinit_svc();
14644#endif
14645
Jeff Johnson295189b2012-06-20 16:38:30 -070014646 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14647 }
14648 else
14649 {
14650 //Send WLAN UP indication to Nlink Service
14651 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14652
14653 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014654 }
14655
14656 EXIT();
14657
14658 return ret_status;
14659}
14660
Jeff Johnson32d95a32012-09-10 13:15:23 -070014661/**---------------------------------------------------------------------------
14662
14663 \brief hdd_module_init() - Init Function
14664
14665 This is the driver entry point (invoked when module is loaded using insmod)
14666
14667 \param - None
14668
14669 \return - 0 for success, non zero for failure
14670
14671 --------------------------------------------------------------------------*/
14672#ifdef MODULE
14673static int __init hdd_module_init ( void)
14674{
14675 return hdd_driver_init();
14676}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014677#else /* #ifdef MODULE */
14678static int __init hdd_module_init ( void)
14679{
14680 /* Driver initialization is delayed to fwpath_changed_handler */
14681 return 0;
14682}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014683#endif /* #ifdef MODULE */
14684
Jeff Johnson295189b2012-06-20 16:38:30 -070014685
14686/**---------------------------------------------------------------------------
14687
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014688 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014689
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014690 This is the driver exit point (invoked when module is unloaded using rmmod
14691 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014692
14693 \param - None
14694
14695 \return - None
14696
14697 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014698static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014699{
14700 hdd_context_t *pHddCtx = NULL;
14701 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014702 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014703 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014704
14705 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14706
14707 //Get the global vos context
14708 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14709
14710 if(!pVosContext)
14711 {
14712 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14713 goto done;
14714 }
14715
14716 //Get the HDD context.
14717 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14718
14719 if(!pHddCtx)
14720 {
14721 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14722 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014723 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14724 {
14725 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14726 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14727 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14728 hdd_wlan_exit(pHddCtx);
14729 vos_preClose( &pVosContext );
14730 goto done;
14731 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014732 else
14733 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014734 /* We wait for active entry threads to exit from driver
14735 * by waiting until rtnl_lock is available.
14736 */
14737 rtnl_lock();
14738 rtnl_unlock();
14739
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014740 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14741 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14742 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14743 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014745 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014746 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14747 msecs_to_jiffies(30000));
14748 if(!rc)
14749 {
14750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14751 "%s:SSR timedout, fatal error", __func__);
14752 VOS_BUG(0);
14753 }
14754 }
14755
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014756 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14757 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014758
c_hpothu8adb97b2014-12-08 19:38:20 +053014759 /* Driver Need to send country code 00 in below condition
14760 * 1) If gCountryCodePriority is set to 1; and last country
14761 * code set is through 11d. This needs to be done in case
14762 * when NV country code is 00.
14763 * This Needs to be done as when kernel store last country
14764 * code and if stored country code is not through 11d,
14765 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14766 * in next load/unload as soon as we get any country through
14767 * 11d. In sme_HandleChangeCountryCodeByUser
14768 * pMsg->countryCode will be last countryCode and
14769 * pMac->scan.countryCode11d will be country through 11d so
14770 * due to mismatch driver will disable 11d.
14771 *
14772 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014773
c_hpothu8adb97b2014-12-08 19:38:20 +053014774 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014775 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014776 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014777 {
14778 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014779 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014780 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14781 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014782
c_hpothu8adb97b2014-12-08 19:38:20 +053014783 //Do all the cleanup before deregistering the driver
14784 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014785 }
14786
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 vos_preClose( &pVosContext );
14788
14789#ifdef TIMER_MANAGER
14790 vos_timer_exit();
14791#endif
14792#ifdef MEMORY_DEBUG
14793 vos_mem_exit();
14794#endif
14795
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014796#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14797 wlan_logging_sock_deinit_svc();
14798#endif
14799
Jeff Johnson295189b2012-06-20 16:38:30 -070014800done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014801 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014802
Jeff Johnson295189b2012-06-20 16:38:30 -070014803 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14804}
14805
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014806/**---------------------------------------------------------------------------
14807
14808 \brief hdd_module_exit() - Exit function
14809
14810 This is the driver exit point (invoked when module is unloaded using rmmod)
14811
14812 \param - None
14813
14814 \return - None
14815
14816 --------------------------------------------------------------------------*/
14817static void __exit hdd_module_exit(void)
14818{
14819 hdd_driver_exit();
14820}
14821
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014822#ifdef MODULE
14823static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014824 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014825{
Jeff Johnson76052702013-04-16 13:55:05 -070014826 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014827}
14828
14829static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014830 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014831{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014832 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014833}
14834#else /* #ifdef MODULE */
14835/**---------------------------------------------------------------------------
14836
Jeff Johnson76052702013-04-16 13:55:05 -070014837 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014838
Jeff Johnson76052702013-04-16 13:55:05 -070014839 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014840 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014841 - invoked when module parameter fwpath is modified from userspace to signal
14842 initializing the WLAN driver or when con_mode is modified from userspace
14843 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014844
14845 \return - 0 for success, non zero for failure
14846
14847 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014848static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014849{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014850 int ret_status;
14851
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014852 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014853 ret_status = hdd_driver_init();
14854 wlan_hdd_inited = ret_status ? 0 : 1;
14855 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014856 }
14857
14858 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014859
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014860 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014861
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014862 ret_status = hdd_driver_init();
14863 wlan_hdd_inited = ret_status ? 0 : 1;
14864 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014865}
14866
Jeff Johnson295189b2012-06-20 16:38:30 -070014867/**---------------------------------------------------------------------------
14868
Jeff Johnson76052702013-04-16 13:55:05 -070014869 \brief fwpath_changed_handler() - Handler Function
14870
14871 Handle changes to the fwpath parameter
14872
14873 \return - 0 for success, non zero for failure
14874
14875 --------------------------------------------------------------------------*/
14876static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014877 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014878{
14879 int ret;
14880
14881 ret = param_set_copystring(kmessage, kp);
14882 if (0 == ret)
14883 ret = kickstart_driver();
14884 return ret;
14885}
14886
14887/**---------------------------------------------------------------------------
14888
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014889 \brief con_mode_handler() -
14890
14891 Handler function for module param con_mode when it is changed by userspace
14892 Dynamically linked - do nothing
14893 Statically linked - exit and init driver, as in rmmod and insmod
14894
Jeff Johnson76052702013-04-16 13:55:05 -070014895 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014896
Jeff Johnson76052702013-04-16 13:55:05 -070014897 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014898
14899 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014900static int con_mode_handler(const char *kmessage,
14901 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014902{
Jeff Johnson76052702013-04-16 13:55:05 -070014903 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014904
Jeff Johnson76052702013-04-16 13:55:05 -070014905 ret = param_set_int(kmessage, kp);
14906 if (0 == ret)
14907 ret = kickstart_driver();
14908 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014909}
14910#endif /* #ifdef MODULE */
14911
14912/**---------------------------------------------------------------------------
14913
Jeff Johnson295189b2012-06-20 16:38:30 -070014914 \brief hdd_get_conparam() -
14915
14916 This is the driver exit point (invoked when module is unloaded using rmmod)
14917
14918 \param - None
14919
14920 \return - tVOS_CON_MODE
14921
14922 --------------------------------------------------------------------------*/
14923tVOS_CON_MODE hdd_get_conparam ( void )
14924{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014925#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014927#else
14928 return (tVOS_CON_MODE)curr_con_mode;
14929#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014930}
14931void hdd_set_conparam ( v_UINT_t newParam )
14932{
14933 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014934#ifndef MODULE
14935 curr_con_mode = con_mode;
14936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014937}
14938/**---------------------------------------------------------------------------
14939
14940 \brief hdd_softap_sta_deauth() - function
14941
14942 This to take counter measure to handle deauth req from HDD
14943
14944 \param - pAdapter - Pointer to the HDD
14945
14946 \param - enable - boolean value
14947
14948 \return - None
14949
14950 --------------------------------------------------------------------------*/
14951
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014952VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14953 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014954{
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014956 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014957 struct hdd_cache_sta_info *cache_sta_info;
14958 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014959
14960 ENTER();
14961
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014962 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014963 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014964
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014965 if (!pSapCtx) {
14966 hddLog(LOGE, "sap context is NULL");
14967 return vosStatus;
14968 }
14969
14970 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14971 pDelStaParams->peerMacAddr);
14972 if (cache_sta_info) {
14973 cache_sta_info->reason_code = pDelStaParams->reason_code;
14974 cache_sta_info->rx_rate =
14975 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14976 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14977 &cache_sta_info->rssi);
14978 }
14979
Jeff Johnson295189b2012-06-20 16:38:30 -070014980 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014981 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014982 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014983
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014984 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014985
14986 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014987 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014988}
14989
14990/**---------------------------------------------------------------------------
14991
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014992 \brief hdd_del_all_sta() - function
14993
14994 This function removes all the stations associated on stopping AP/P2P GO.
14995
14996 \param - pAdapter - Pointer to the HDD
14997
14998 \return - None
14999
15000 --------------------------------------------------------------------------*/
15001
15002int hdd_del_all_sta(hdd_adapter_t *pAdapter)
15003{
15004 v_U16_t i;
15005 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015006 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15007 ptSapContext pSapCtx = NULL;
15008 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15009 if(pSapCtx == NULL){
15010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15011 FL("psapCtx is NULL"));
15012 return 1;
15013 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015014 ENTER();
15015
15016 hddLog(VOS_TRACE_LEVEL_INFO,
15017 "%s: Delete all STAs associated.",__func__);
15018 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
15019 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
15020 )
15021 {
15022 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15023 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015024 if ((pSapCtx->aStaInfo[i].isUsed) &&
15025 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015026 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015027 struct tagCsrDelStaParams delStaParams;
15028
15029 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015030 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015031 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
15032 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015033 &delStaParams);
15034 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015035 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015036 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015037 }
15038 }
15039 }
15040
15041 EXIT();
15042 return 0;
15043}
15044
15045/**---------------------------------------------------------------------------
15046
Jeff Johnson295189b2012-06-20 16:38:30 -070015047 \brief hdd_softap_sta_disassoc() - function
15048
15049 This to take counter measure to handle deauth req from HDD
15050
15051 \param - pAdapter - Pointer to the HDD
15052
15053 \param - enable - boolean value
15054
15055 \return - None
15056
15057 --------------------------------------------------------------------------*/
15058
15059void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
15060{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015061 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15062 struct hdd_cache_sta_info *cache_sta_info;
15063 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015064
15065 ENTER();
15066
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015067 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015068
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015069 if (!pSapCtx) {
15070 hddLog(LOGE, "sap context is NULL");
15071 return ;
15072 }
15073
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 //Ignore request to disassoc bcmc station
15075 if( pDestMacAddress[0] & 0x1 )
15076 return;
15077
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015078 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
15079 pDestMacAddress);
15080 if (cache_sta_info) {
15081 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
15082 cache_sta_info->rx_rate =
15083 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15084 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15085 &cache_sta_info->rssi);
15086 }
15087
Jeff Johnson295189b2012-06-20 16:38:30 -070015088 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
15089}
15090
15091void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15092{
15093 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15094
15095 ENTER();
15096
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015097 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015098
15099 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15100}
15101
Jeff Johnson295189b2012-06-20 16:38:30 -070015102/**---------------------------------------------------------------------------
15103 *
15104 * \brief hdd_get__concurrency_mode() -
15105 *
15106 *
15107 * \param - None
15108 *
15109 * \return - CONCURRENCY MODE
15110 *
15111 * --------------------------------------------------------------------------*/
15112tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15113{
15114 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15115 hdd_context_t *pHddCtx;
15116
15117 if (NULL != pVosContext)
15118 {
15119 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15120 if (NULL != pHddCtx)
15121 {
15122 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15123 }
15124 }
15125
15126 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015127 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 return VOS_STA;
15129}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015130v_BOOL_t
15131wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15132{
15133 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015134
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015135 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15136 if (pAdapter == NULL)
15137 {
15138 hddLog(VOS_TRACE_LEVEL_INFO,
15139 FL("GO doesn't exist"));
15140 return TRUE;
15141 }
15142 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15143 {
15144 hddLog(VOS_TRACE_LEVEL_INFO,
15145 FL("GO started"));
15146 return TRUE;
15147 }
15148 else
15149 /* wait till GO changes its interface to p2p device */
15150 hddLog(VOS_TRACE_LEVEL_INFO,
15151 FL("Del_bss called, avoid apps suspend"));
15152 return FALSE;
15153
15154}
Jeff Johnson295189b2012-06-20 16:38:30 -070015155/* Decide whether to allow/not the apps power collapse.
15156 * Allow apps power collapse if we are in connected state.
15157 * if not, allow only if we are in IMPS */
15158v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15159{
15160 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015161 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015162 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15164 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15165 hdd_adapter_t *pAdapter = NULL;
15166 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015167 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015168
Jeff Johnson295189b2012-06-20 16:38:30 -070015169 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15170 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015171
Yathish9f22e662012-12-10 14:21:35 -080015172 concurrent_state = hdd_get_concurrency_mode();
15173
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015174 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15175 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15176 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015177#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015178
Yathish9f22e662012-12-10 14:21:35 -080015179 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015180 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015181 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15182 return TRUE;
15183#endif
15184
Jeff Johnson295189b2012-06-20 16:38:30 -070015185 /*loop through all adapters. TBD fix for Concurrency */
15186 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15187 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15188 {
15189 pAdapter = pAdapterNode->pAdapter;
15190 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15191 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15192 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015193 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015194 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015195 && pmcState != STOPPED && pmcState != STANDBY &&
15196 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015197 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15198 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015199 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015200 if(pmcState == FULL_POWER &&
15201 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15202 {
15203 /*
15204 * When SCO indication comes from Coex module , host will
15205 * enter in to full power mode, but this should not prevent
15206 * apps processor power collapse.
15207 */
15208 hddLog(LOG1,
15209 FL("Allow apps power collapse"
15210 "even when sco indication is set"));
15211 return TRUE;
15212 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015213 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015214 "pmcState = %d scanRspPending = %d "
15215 "inMiddleOfRoaming = %d connected = %d",
15216 __func__, pmcState, scanRspPending,
15217 inMiddleOfRoaming, hdd_connIsConnected(
15218 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15219 wlan_hdd_get_tdls_stats(pAdapter);
15220 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 }
15222 }
15223 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15224 pAdapterNode = pNext;
15225 }
15226 return TRUE;
15227}
15228
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015229/* Decides whether to send suspend notification to Riva
15230 * if any adapter is in BMPS; then it is required */
15231v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15232{
15233 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15234 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15235
15236 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15237 {
15238 return TRUE;
15239 }
15240 return FALSE;
15241}
15242
Jeff Johnson295189b2012-06-20 16:38:30 -070015243void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15244{
15245 switch(mode)
15246 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015247 case VOS_STA_MODE:
15248 case VOS_P2P_CLIENT_MODE:
15249 case VOS_P2P_GO_MODE:
15250 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015251 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015252 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015253 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015254 break;
15255 default:
15256 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015257 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015258 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15259 "Number of open sessions for mode %d = %d"),
15260 pHddCtx->concurrency_mode, mode,
15261 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015262}
15263
15264
15265void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15266{
15267 switch(mode)
15268 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015269 case VOS_STA_MODE:
15270 case VOS_P2P_CLIENT_MODE:
15271 case VOS_P2P_GO_MODE:
15272 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015273 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015274 pHddCtx->no_of_open_sessions[mode]--;
15275 if (!(pHddCtx->no_of_open_sessions[mode]))
15276 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015277 break;
15278 default:
15279 break;
15280 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015281 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15282 "Number of open sessions for mode %d = %d"),
15283 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15284
15285}
15286/**---------------------------------------------------------------------------
15287 *
15288 * \brief wlan_hdd_incr_active_session()
15289 *
15290 * This function increments the number of active sessions
15291 * maintained per device mode
15292 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15293 * Incase of SAP/P2P GO upon bss start it is incremented
15294 *
15295 * \param pHddCtx - HDD Context
15296 * \param mode - device mode
15297 *
15298 * \return - None
15299 *
15300 * --------------------------------------------------------------------------*/
15301void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15302{
15303 switch (mode) {
15304 case VOS_STA_MODE:
15305 case VOS_P2P_CLIENT_MODE:
15306 case VOS_P2P_GO_MODE:
15307 case VOS_STA_SAP_MODE:
15308 pHddCtx->no_of_active_sessions[mode]++;
15309 break;
15310 default:
15311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15312 break;
15313 }
15314 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15315 mode,
15316 pHddCtx->no_of_active_sessions[mode]);
15317}
15318
15319/**---------------------------------------------------------------------------
15320 *
15321 * \brief wlan_hdd_decr_active_session()
15322 *
15323 * This function decrements the number of active sessions
15324 * maintained per device mode
15325 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15326 * Incase of SAP/P2P GO upon bss stop it is decremented
15327 *
15328 * \param pHddCtx - HDD Context
15329 * \param mode - device mode
15330 *
15331 * \return - None
15332 *
15333 * --------------------------------------------------------------------------*/
15334void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15335{
Bhargav Shahd0715912015-10-01 18:17:37 +053015336
Agarwal Ashish51325b52014-06-16 16:50:49 +053015337 switch (mode) {
15338 case VOS_STA_MODE:
15339 case VOS_P2P_CLIENT_MODE:
15340 case VOS_P2P_GO_MODE:
15341 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015342 if (pHddCtx->no_of_active_sessions[mode] > 0)
15343 pHddCtx->no_of_active_sessions[mode]--;
15344 else
15345 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15346 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015347 break;
15348 default:
15349 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15350 break;
15351 }
15352 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15353 mode,
15354 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015355}
15356
Jeff Johnsone7245742012-09-05 17:12:55 -070015357/**---------------------------------------------------------------------------
15358 *
15359 * \brief wlan_hdd_restart_init
15360 *
15361 * This function initalizes restart timer/flag. An internal function.
15362 *
15363 * \param - pHddCtx
15364 *
15365 * \return - None
15366 *
15367 * --------------------------------------------------------------------------*/
15368
15369static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15370{
15371 /* Initialize */
15372 pHddCtx->hdd_restart_retries = 0;
15373 atomic_set(&pHddCtx->isRestartInProgress, 0);
15374 vos_timer_init(&pHddCtx->hdd_restart_timer,
15375 VOS_TIMER_TYPE_SW,
15376 wlan_hdd_restart_timer_cb,
15377 pHddCtx);
15378}
15379/**---------------------------------------------------------------------------
15380 *
15381 * \brief wlan_hdd_restart_deinit
15382 *
15383 * This function cleans up the resources used. An internal function.
15384 *
15385 * \param - pHddCtx
15386 *
15387 * \return - None
15388 *
15389 * --------------------------------------------------------------------------*/
15390
15391static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15392{
15393
15394 VOS_STATUS vos_status;
15395 /* Block any further calls */
15396 atomic_set(&pHddCtx->isRestartInProgress, 1);
15397 /* Cleanup */
15398 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15399 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015400 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015401 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15402 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015403 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015404
15405}
15406
15407/**---------------------------------------------------------------------------
15408 *
15409 * \brief wlan_hdd_framework_restart
15410 *
15411 * This function uses a cfg80211 API to start a framework initiated WLAN
15412 * driver module unload/load.
15413 *
15414 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15415 *
15416 *
15417 * \param - pHddCtx
15418 *
15419 * \return - VOS_STATUS_SUCCESS: Success
15420 * VOS_STATUS_E_EMPTY: Adapter is Empty
15421 * VOS_STATUS_E_NOMEM: No memory
15422
15423 * --------------------------------------------------------------------------*/
15424
15425static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15426{
15427 VOS_STATUS status = VOS_STATUS_SUCCESS;
15428 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015429 int len = (sizeof (struct ieee80211_mgmt));
15430 struct ieee80211_mgmt *mgmt = NULL;
15431
15432 /* Prepare the DEAUTH managment frame with reason code */
15433 mgmt = kzalloc(len, GFP_KERNEL);
15434 if(mgmt == NULL)
15435 {
15436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15437 "%s: memory allocation failed (%d bytes)", __func__, len);
15438 return VOS_STATUS_E_NOMEM;
15439 }
15440 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015441
15442 /* Iterate over all adapters/devices */
15443 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015444 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15445 {
15446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015447 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015448 goto end;
15449 }
15450
Jeff Johnsone7245742012-09-05 17:12:55 -070015451 do
15452 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015453 if(pAdapterNode->pAdapter &&
15454 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015455 {
15456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15457 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15458 pAdapterNode->pAdapter->dev->name,
15459 pAdapterNode->pAdapter->device_mode,
15460 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015461 /*
15462 * CFG80211 event to restart the driver
15463 *
15464 * 'cfg80211_send_unprot_deauth' sends a
15465 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15466 * of SME(Linux Kernel) state machine.
15467 *
15468 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15469 * the driver.
15470 *
15471 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015472
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15474 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15475#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015476 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015477#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015478 }
15479 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15480 pAdapterNode = pNext;
15481 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15482
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015483 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015484 /* Free the allocated management frame */
15485 kfree(mgmt);
15486
Jeff Johnsone7245742012-09-05 17:12:55 -070015487 /* Retry until we unload or reach max count */
15488 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15489 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15490
15491 return status;
15492
15493}
15494/**---------------------------------------------------------------------------
15495 *
15496 * \brief wlan_hdd_restart_timer_cb
15497 *
15498 * Restart timer callback. An internal function.
15499 *
15500 * \param - User data:
15501 *
15502 * \return - None
15503 *
15504 * --------------------------------------------------------------------------*/
15505
15506void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15507{
15508 hdd_context_t *pHddCtx = usrDataForCallback;
15509 wlan_hdd_framework_restart(pHddCtx);
15510 return;
15511
15512}
15513
15514
15515/**---------------------------------------------------------------------------
15516 *
15517 * \brief wlan_hdd_restart_driver
15518 *
15519 * This function sends an event to supplicant to restart the WLAN driver.
15520 *
15521 * This function is called from vos_wlanRestart.
15522 *
15523 * \param - pHddCtx
15524 *
15525 * \return - VOS_STATUS_SUCCESS: Success
15526 * VOS_STATUS_E_EMPTY: Adapter is Empty
15527 * VOS_STATUS_E_ALREADY: Request already in progress
15528
15529 * --------------------------------------------------------------------------*/
15530VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15531{
15532 VOS_STATUS status = VOS_STATUS_SUCCESS;
15533
15534 /* A tight check to make sure reentrancy */
15535 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15536 {
Mihir Shetefd528652014-06-23 19:07:50 +053015537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015538 "%s: WLAN restart is already in progress", __func__);
15539
15540 return VOS_STATUS_E_ALREADY;
15541 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015542 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015543#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015544 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015545#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015546
Jeff Johnsone7245742012-09-05 17:12:55 -070015547 return status;
15548}
15549
Bhargav Shahd0715912015-10-01 18:17:37 +053015550/**
15551 * hdd_get_total_sessions() - provide total number of active sessions
15552 * @pHddCtx: Valid Global HDD context pointer
15553 *
15554 * This function iterates through pAdaptors and find the number of all active
15555 * sessions. This active sessions includes connected sta, p2p client and number
15556 * of client connected to sap/p2p go.
15557 *
15558 * Return: Total number of active sessions.
15559 */
15560v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15561{
15562 v_U8_t active_session = 0;
15563 hdd_station_ctx_t *pHddStaCtx;
15564 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15565 hdd_adapter_t *pAdapter;
15566 VOS_STATUS status;
15567
15568 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15569 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15570 pAdapter = pAdapterNode->pAdapter;
15571 switch (pAdapter->device_mode) {
15572 case VOS_STA_MODE:
15573 case VOS_P2P_CLIENT_MODE:
15574 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15575 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15576 active_session += 1;
15577 break;
15578 case VOS_STA_SAP_MODE:
15579 case VOS_P2P_GO_MODE:
15580 active_session += hdd_softap_get_connected_sta(pAdapter);
15581 break;
15582 default:
15583 break;
15584 }
15585
15586 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15587 pAdapterNode = pNext;
15588 }
15589
15590 return active_session;
15591}
15592
15593/**
15594 * hdd_set_delack_value() - Set delack value
15595 * @pHddCtx: Valid Global HDD context pointer
15596 * @next_rx_level: Value to set for delack
15597 *
15598 * This function compare present value and next value of delack. If the both
15599 * are diffrent then it sets next value .
15600 *
15601 * Return: void.
15602 */
15603void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15604{
15605 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015606 struct wlan_rx_tp_data rx_tp_data = {0};
15607
Bhargav Shahd0715912015-10-01 18:17:37 +053015608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15609 "%s: TCP DELACK trigger level %d",
15610 __func__, next_rx_level);
15611 mutex_lock(&pHddCtx->cur_rx_level_lock);
15612 pHddCtx->cur_rx_level = next_rx_level;
15613 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015614
15615 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15616 rx_tp_data.level = next_rx_level;
15617
15618 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15619 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015620 }
15621}
15622
15623/**
15624 * hdd_set_default_stop_delack_timer() - Start delack timer
15625 * @pHddCtx: Valid Global HDD context pointer
15626 *
15627 * This function stop delack timer and set delack value to default..
15628 *
15629 * Return: void.
15630 */
15631
15632void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15633{
15634 if (VOS_TIMER_STATE_RUNNING !=
15635 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15637 "%s: Can not stop timer", __func__);
15638 return;
15639 }
15640
15641 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015642 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015643}
15644
15645/**
15646 * hdd_start_delack_timer() - Start delack timer
15647 * @pHddCtx: Valid Global HDD context pointer
15648 *
15649 * This function starts the delack timer for tcpDelAckComputeInterval time
15650 * interval.The default timer value is 2 second.
15651 *
15652 * Return: void.
15653 */
15654void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15655{
15656 if (VOS_TIMER_STATE_RUNNING ==
15657 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15659 "%s: Timer is already running", __func__);
15660 return;
15661 }
15662
15663 vos_timer_start(&pHddCtx->delack_timer,
15664 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15665}
15666
15667/**
15668 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15669 * @pHddCtx: Valid Global HDD context pointer
15670 *
15671 * This function updates the prev_rx_packets count from the corresponding
15672 * pAdapter states. This prev_rx_packets will diffed with the packet count
15673 * at the end of delack timer. That can give number of RX packet is spacific
15674 * time.
15675 *
15676 * Return: void.
15677 */
15678void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15679{
15680 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15681 hdd_adapter_t *pAdapter;
15682 VOS_STATUS status;
15683
15684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15685 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15686 pAdapter = pAdapterNode->pAdapter;
15687 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15688 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15689 pAdapterNode = pNext;
15690 }
15691}
15692
15693/**
15694 * hdd_manage_delack_timer() - start\stop delack timer
15695 * @pHddCtx: Valid Global HDD context pointer
15696 *
15697 * This function check the number of concerent session present, it starts the
15698 * delack timer if only one session is present.
15699 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15700 *
15701 * Return: void.
15702 */
15703void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15704{
15705 uint8_t sessions;
15706
15707 if (!pHddCtx->cfg_ini->enable_delack) {
15708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15709 "%s: TCP DELACK is not enabled", __func__);
15710 return;
15711 }
15712
15713 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15714 if (pHddCtx->mode != 0) {
15715 hdd_set_default_stop_delack_timer(pHddCtx);
15716 return;
15717 }
15718
15719 sessions = hdd_get_total_sessions(pHddCtx);
15720 if (sessions == 1) {
15721 hdd_update_prev_rx_packet_count(pHddCtx);
15722 hdd_start_delack_timer(pHddCtx);
15723 } else {
15724 hdd_set_default_stop_delack_timer(pHddCtx);
15725 }
15726}
15727
Mihir Shetee1093ba2014-01-21 20:13:32 +053015728/**---------------------------------------------------------------------------
15729 *
15730 * \brief wlan_hdd_init_channels
15731 *
15732 * This function is used to initialize the channel list in CSR
15733 *
15734 * This function is called from hdd_wlan_startup
15735 *
15736 * \param - pHddCtx: HDD context
15737 *
15738 * \return - VOS_STATUS_SUCCESS: Success
15739 * VOS_STATUS_E_FAULT: Failure reported by SME
15740
15741 * --------------------------------------------------------------------------*/
15742static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15743{
15744 eHalStatus status;
15745
15746 status = sme_InitChannels(pHddCtx->hHal);
15747 if (HAL_STATUS_SUCCESS(status))
15748 {
15749 return VOS_STATUS_SUCCESS;
15750 }
15751 else
15752 {
15753 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15754 __func__, status);
15755 return VOS_STATUS_E_FAULT;
15756 }
15757}
15758
Mihir Shete04206452014-11-20 17:50:58 +053015759#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015760VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015761{
15762 eHalStatus status;
15763
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015764 if (init == INIT && init_by_reg_core_user) {
15765 init_by_reg_core_user = false;
15766 pr_info("driver regulatory hint is not required");
15767
15768 return VOS_STATUS_SUCCESS;
15769 }
15770
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015771 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015772 if (HAL_STATUS_SUCCESS(status))
15773 {
15774 return VOS_STATUS_SUCCESS;
15775 }
15776 else
15777 {
15778 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15779 __func__, status);
15780 return VOS_STATUS_E_FAULT;
15781 }
15782}
Mihir Shete04206452014-11-20 17:50:58 +053015783#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015784/*
15785 * API to find if there is any STA or P2P-Client is connected
15786 */
15787VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15788{
15789 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15790}
Jeff Johnsone7245742012-09-05 17:12:55 -070015791
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015792
15793/*
15794 * API to find if the firmware will send logs using DXE channel
15795 */
15796v_U8_t hdd_is_fw_logging_enabled(void)
15797{
15798 hdd_context_t *pHddCtx;
15799
15800 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15801 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15802
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015803 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15804 pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015805}
15806
Agarwal Ashish57e84372014-12-05 18:26:53 +053015807/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015808 * API to find if the firmware will send trace logs using DXE channel
15809 */
15810v_U8_t hdd_is_fw_ev_logging_enabled(void)
15811{
15812 hdd_context_t *pHddCtx;
15813
15814 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15815 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15816
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015817 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15818 pHddCtx->cfg_ini->enableFWLogging);
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015819}
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015820
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015821/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015822 * API to find if there is any session connected
15823 */
15824VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15825{
15826 return sme_is_any_session_connected(pHddCtx->hHal);
15827}
15828
15829
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015830int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15831{
15832 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15833 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015834 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015835 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015836
15837 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015838 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015839 if (pScanInfo->mScanPending)
15840 {
c_hpothua3d45d52015-01-05 14:11:17 +053015841 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15842 eCSR_SCAN_ABORT_DEFAULT);
15843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15844 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015845
c_hpothua3d45d52015-01-05 14:11:17 +053015846 /* If there is active scan command lets wait for the completion else
15847 * there is no need to wait as scan command might be in the SME pending
15848 * command list.
15849 */
15850 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15851 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015852 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015853 &pScanInfo->abortscan_event_var,
15854 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015855 if (0 >= status)
15856 {
15857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015858 "%s: Timeout or Interrupt occurred while waiting for abort"
15859 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015860 return -ETIMEDOUT;
15861 }
15862 }
15863 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15864 {
15865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15866 FL("hdd_abort_mac_scan failed"));
15867 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015868 }
15869 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015870 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015871}
15872
Abhishek Singh7d624e12015-11-30 14:29:27 +053015873/**
15874 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15875 * user space
15876 * @frame_ind: Management frame data to be informed.
15877 *
15878 * This function is used to indicate management frame to
15879 * user space
15880 *
15881 * Return: None
15882 *
15883 */
15884void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15885{
15886 hdd_context_t *hdd_ctx = NULL;
15887 hdd_adapter_t *adapter = NULL;
15888 v_CONTEXT_t vos_context = NULL;
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015889 struct ieee80211_mgmt *mgmt =
15890 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Abhishek Singh7d624e12015-11-30 14:29:27 +053015891
15892 /* Get the global VOSS context.*/
15893 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15894 if (!vos_context) {
15895 hddLog(LOGE, FL("Global VOS context is Null"));
15896 return;
15897 }
15898 /* Get the HDD context.*/
15899 hdd_ctx =
15900 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15901
15902 if (0 != wlan_hdd_validate_context(hdd_ctx))
15903 {
15904 return;
15905 }
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015906
15907 if (frame_ind->frameLen < ieee80211_hdrlen(mgmt->frame_control)) {
15908 hddLog(LOGE, FL(" Invalid frame length"));
15909 return;
15910 }
15911
Abhishek Singh7d624e12015-11-30 14:29:27 +053015912 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15913 frame_ind->sessionId);
15914
15915 if ((NULL != adapter) &&
15916 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15917 __hdd_indicate_mgmt_frame(adapter,
15918 frame_ind->frameLen,
15919 frame_ind->frameBuf,
15920 frame_ind->frameType,
15921 frame_ind->rxChan,
15922 frame_ind->rxRssi);
15923 return;
15924
15925}
15926
c_hpothu225aa7c2014-10-22 17:45:13 +053015927VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15928{
15929 hdd_adapter_t *pAdapter;
15930 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15931 VOS_STATUS vosStatus;
15932
15933 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15934 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15935 {
15936 pAdapter = pAdapterNode->pAdapter;
15937 if (NULL != pAdapter)
15938 {
15939 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15940 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15941 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15942 {
15943 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15944 pAdapter->device_mode);
15945 if (VOS_STATUS_SUCCESS !=
15946 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15947 {
15948 hddLog(LOGE, FL("failed to abort ROC"));
15949 return VOS_STATUS_E_FAILURE;
15950 }
15951 }
15952 }
15953 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15954 pAdapterNode = pNext;
15955 }
15956 return VOS_STATUS_SUCCESS;
15957}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015958
Mihir Shete0be28772015-02-17 18:42:14 +053015959hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15960{
15961 hdd_adapter_t *pAdapter;
15962 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15963 hdd_cfg80211_state_t *cfgState;
15964 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15965 VOS_STATUS vosStatus;
15966
15967 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15968 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15969 {
15970 pAdapter = pAdapterNode->pAdapter;
15971 if (NULL != pAdapter)
15972 {
15973 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15974 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15975 if (pRemainChanCtx)
15976 break;
15977 }
15978 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15979 pAdapterNode = pNext;
15980 }
15981 return pRemainChanCtx;
15982}
15983
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015984/**
15985 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15986 *
15987 * @pHddCtx: HDD context within host driver
15988 * @dfsScanMode: dfsScanMode passed from ioctl
15989 *
15990 */
15991
15992VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15993 tANI_U8 dfsScanMode)
15994{
15995 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15996 hdd_adapter_t *pAdapter;
15997 VOS_STATUS vosStatus;
15998 hdd_station_ctx_t *pHddStaCtx;
15999 eHalStatus status = eHAL_STATUS_SUCCESS;
16000
16001 if(!pHddCtx)
16002 {
16003 hddLog(LOGE, FL("HDD context is Null"));
16004 return eHAL_STATUS_FAILURE;
16005 }
16006
16007 if (pHddCtx->scan_info.mScanPending)
16008 {
16009 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
16010 pHddCtx->scan_info.sessionId);
16011 hdd_abort_mac_scan(pHddCtx,
16012 pHddCtx->scan_info.sessionId,
16013 eCSR_SCAN_ABORT_DEFAULT);
16014 }
16015
16016 if (!dfsScanMode)
16017 {
16018 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
16019 while ((NULL != pAdapterNode) &&
16020 (VOS_STATUS_SUCCESS == vosStatus))
16021 {
16022 pAdapter = pAdapterNode->pAdapter;
16023
16024 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
16025 {
16026 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16027
16028 if(!pHddStaCtx)
16029 {
16030 hddLog(LOGE, FL("HDD STA context is Null"));
16031 return eHAL_STATUS_FAILURE;
16032 }
16033
16034 /* if STA is already connected on DFS channel,
16035 disconnect immediately*/
16036 if (hdd_connIsConnected(pHddStaCtx) &&
16037 (NV_CHANNEL_DFS ==
16038 vos_nv_getChannelEnabledState(
16039 pHddStaCtx->conn_info.operationChannel)))
16040 {
16041 status = sme_RoamDisconnect(pHddCtx->hHal,
16042 pAdapter->sessionId,
16043 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16044 hddLog(LOG1, FL("Client connected on DFS channel %d,"
16045 "sme_RoamDisconnect returned with status: %d"
16046 "for sessionid: %d"), pHddStaCtx->conn_info.
16047 operationChannel, status, pAdapter->sessionId);
16048 }
16049 }
16050
16051 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
16052 &pNext);
16053 pAdapterNode = pNext;
16054 }
16055 }
16056
16057 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
16058 sme_UpdateDFSRoamMode(pHddCtx->hHal,
16059 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
16060
16061 status = sme_HandleDFSChanScan(pHddCtx->hHal);
16062 if (!HAL_STATUS_SUCCESS(status))
16063 {
16064 hddLog(LOGE,
16065 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
16066 return status;
16067 }
16068
16069 return status;
16070}
16071
Nirav Shah7e3c8132015-06-22 23:51:42 +053016072static int hdd_log2_ceil(unsigned value)
16073{
16074 /* need to switch to unsigned math so that negative values
16075 * will right-shift towards 0 instead of -1
16076 */
16077 unsigned tmp = value;
16078 int log2 = -1;
16079
16080 if (value == 0)
16081 return 0;
16082
16083 while (tmp) {
16084 log2++;
16085 tmp >>= 1;
16086 }
16087 if (1U << log2 != value)
16088 log2++;
16089
16090 return log2;
16091}
16092
16093/**
16094 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
16095 * @pAdapter: adapter handle
16096 *
16097 * Return: vos status
16098 */
16099VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
16100{
16101 int hash_elem, log2, i;
16102
16103 spin_lock_bh( &pAdapter->sta_hash_lock);
16104 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16105 spin_unlock_bh( &pAdapter->sta_hash_lock);
16106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16107 "%s: hash already attached for session id %d",
16108 __func__, pAdapter->sessionId);
16109 return VOS_STATUS_SUCCESS;
16110 }
16111 spin_unlock_bh( &pAdapter->sta_hash_lock);
16112
16113 hash_elem = WLAN_MAX_STA_COUNT;
16114 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16115 log2 = hdd_log2_ceil(hash_elem);
16116 hash_elem = 1 << log2;
16117
16118 pAdapter->sta_id_hash.mask = hash_elem - 1;
16119 pAdapter->sta_id_hash.idx_bits = log2;
16120 pAdapter->sta_id_hash.bins =
16121 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16122 if (!pAdapter->sta_id_hash.bins) {
16123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16124 "%s: malloc failed for session %d",
16125 __func__, pAdapter->sessionId);
16126 return VOS_STATUS_E_NOMEM;
16127 }
16128
16129 for (i = 0; i < hash_elem; i++)
16130 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16131
16132 spin_lock_bh( &pAdapter->sta_hash_lock);
16133 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16134 spin_unlock_bh( &pAdapter->sta_hash_lock);
16135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16136 "%s: Station ID Hash attached for session id %d",
16137 __func__, pAdapter->sessionId);
16138
16139 return VOS_STATUS_SUCCESS;
16140}
16141
16142/**
16143 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16144 * @pAdapter: adapter handle
16145 *
16146 * Return: vos status
16147 */
16148VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16149{
16150 int hash_elem, i;
16151 v_SIZE_t size;
16152
16153 spin_lock_bh( &pAdapter->sta_hash_lock);
16154 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16155 spin_unlock_bh( &pAdapter->sta_hash_lock);
16156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16157 "%s: hash not initialized for session id %d",
16158 __func__, pAdapter->sessionId);
16159 return VOS_STATUS_SUCCESS;
16160 }
16161
16162 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16163 spin_unlock_bh( &pAdapter->sta_hash_lock);
16164
16165 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16166
16167 /* free all station info*/
16168 for (i = 0; i < hash_elem; i++) {
16169 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16170 if (size != 0) {
16171 VOS_STATUS status;
16172 hdd_staid_hash_node_t *sta_info_node = NULL;
16173 hdd_staid_hash_node_t *next_node = NULL;
16174 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16175 (hdd_list_node_t**) &sta_info_node );
16176
16177 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16178 {
16179 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16180 &sta_info_node->node);
16181 vos_mem_free(sta_info_node);
16182
16183 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16184 (hdd_list_node_t*)sta_info_node,
16185 (hdd_list_node_t**)&next_node);
16186 sta_info_node = next_node;
16187 }
16188 }
16189 }
16190
16191 vos_mem_free(pAdapter->sta_id_hash.bins);
16192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16193 "%s: Station ID Hash detached for session id %d",
16194 __func__, pAdapter->sessionId);
16195 return VOS_STATUS_SUCCESS;
16196}
16197
16198/**
16199 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16200 * @pAdapter: adapter handle
16201 * @mac_addr_in: input mac address
16202 *
16203 * Return: index derived from mac address
16204 */
16205int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16206 v_MACADDR_t *mac_addr_in)
16207{
16208 uint16 index;
16209 struct hdd_align_mac_addr_t * mac_addr =
16210 (struct hdd_align_mac_addr_t *)mac_addr_in;
16211
16212 index = mac_addr->bytes_ab ^
16213 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16214 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16215 index &= pAdapter->sta_id_hash.mask;
16216 return index;
16217}
16218
16219/**
16220 * hdd_sta_id_hash_add_entry() - add entry in hash
16221 * @pAdapter: adapter handle
16222 * @sta_id: station id
16223 * @mac_addr: mac address
16224 *
16225 * Return: vos status
16226 */
16227VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16228 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16229{
16230 uint16 index;
16231 hdd_staid_hash_node_t *sta_info_node = NULL;
16232
Nirav Shah7e3c8132015-06-22 23:51:42 +053016233 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16234 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16235 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16237 "%s: malloc failed", __func__);
16238 return VOS_STATUS_E_NOMEM;
16239 }
16240
16241 sta_info_node->sta_id = sta_id;
16242 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16243
Nirav Shah303ed5c2015-08-24 10:29:25 +053016244 spin_lock_bh( &pAdapter->sta_hash_lock);
16245 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16246 spin_unlock_bh( &pAdapter->sta_hash_lock);
16247 vos_mem_free(sta_info_node);
16248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16249 "%s: hash is not initialized for session id %d",
16250 __func__, pAdapter->sessionId);
16251 return VOS_STATUS_E_FAILURE;
16252 }
16253
Nirav Shah7e3c8132015-06-22 23:51:42 +053016254 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16255 (hdd_list_node_t*) sta_info_node );
16256 spin_unlock_bh( &pAdapter->sta_hash_lock);
16257 return VOS_STATUS_SUCCESS;
16258}
16259
16260/**
16261 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16262 * @pAdapter: adapter handle
16263 * @sta_id: station id
16264 * @mac_addr: mac address
16265 *
16266 * Return: vos status
16267 */
16268VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16269 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16270{
16271 uint16 index;
16272 VOS_STATUS status;
16273 hdd_staid_hash_node_t *sta_info_node = NULL;
16274 hdd_staid_hash_node_t *next_node = NULL;
16275
16276 spin_lock_bh( &pAdapter->sta_hash_lock);
16277 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16278 spin_unlock_bh( &pAdapter->sta_hash_lock);
16279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16280 "%s: hash is not initialized for session id %d",
16281 __func__, pAdapter->sessionId);
16282 return VOS_STATUS_E_FAILURE;
16283 }
16284
16285 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16286 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16287 (hdd_list_node_t**) &sta_info_node );
16288
16289 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16290 {
16291 if (sta_info_node->sta_id == sta_id) {
16292 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16293 &sta_info_node->node);
16294 vos_mem_free(sta_info_node);
16295 break;
16296 }
16297 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16298 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16299 sta_info_node = next_node;
16300 }
16301 spin_unlock_bh( &pAdapter->sta_hash_lock);
16302 return status;
16303}
16304
16305/**
16306 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16307 * @pAdapter: adapter handle
16308 * @mac_addr_in: mac address
16309 *
16310 * Return: station id
16311 */
16312int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16313 v_MACADDR_t *mac_addr_in)
16314{
16315 uint8 is_found = 0;
16316 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16317 uint16 index;
16318 VOS_STATUS status;
16319 hdd_staid_hash_node_t *sta_info_node = NULL;
16320 hdd_staid_hash_node_t *next_node = NULL;
16321
16322 spin_lock_bh( &pAdapter->sta_hash_lock);
16323 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16324 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016325 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016326 FL("hash is not initialized for session id %d"),
16327 pAdapter->sessionId);
16328 return HDD_WLAN_INVALID_STA_ID;
16329 }
16330
16331 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16332 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16333 (hdd_list_node_t**) &sta_info_node );
16334
16335 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16336 {
16337 if (vos_mem_compare(&sta_info_node->mac_addr,
16338 mac_addr_in, sizeof(v_MACADDR_t))) {
16339 is_found = 1;
16340 sta_id = sta_info_node->sta_id;
16341 break;
16342 }
16343 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16344 (hdd_list_node_t*)sta_info_node,
16345 (hdd_list_node_t**)&next_node);
16346 sta_info_node = next_node;
16347 }
16348 spin_unlock_bh( &pAdapter->sta_hash_lock);
16349 return sta_id;
16350}
16351
c_manjeecfd1efb2015-09-25 19:32:34 +053016352/*FW memory dump feature*/
16353/**
16354 * This structure hold information about the /proc file
16355 *
16356 */
16357static struct proc_dir_entry *proc_file, *proc_dir;
16358
16359/**
16360 * memdump_read() - perform read operation in memory dump proc file
16361 *
16362 * @file - handle for the proc file.
16363 * @buf - pointer to user space buffer.
16364 * @count - number of bytes to be read.
16365 * @pos - offset in the from buffer.
16366 *
16367 * This function performs read operation for the memory dump proc file.
16368 *
16369 * Return: number of bytes read on success, error code otherwise.
16370 */
16371static ssize_t memdump_read(struct file *file, char __user *buf,
16372 size_t count, loff_t *pos)
16373{
16374 int status;
16375 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16376 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016377 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016378 ENTER();
16379
16380 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16381 status = wlan_hdd_validate_context(hdd_ctx);
16382 if (0 != status) {
16383 return -EINVAL;
16384 }
16385
16386 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16387 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16388 return -EINVAL;
16389 }
16390
16391 /* run fs_read_handler in an atomic context*/
16392 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016393 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16394 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016395 {
16396 /*Free the fwr mem dump buffer */
16397 wlan_free_fwr_mem_dump_buffer();
16398 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016399 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016400 }
16401 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16402 vos_ssr_unprotect(__func__);
16403 EXIT();
16404 return ret_count;
16405}
16406
16407/**
16408 * struct memdump_fops - file operations for memory dump feature
16409 * @read - read function for memory dump operation.
16410 *
16411 * This structure initialize the file operation handle for memory
16412 * dump feature
16413 */
16414static const struct file_operations memdump_fops = {
16415 read: memdump_read
16416};
16417
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016418struct fw_mem_dump_priv {
16419 uint32_t status;
16420};
16421
c_manjeecfd1efb2015-09-25 19:32:34 +053016422/*
16423* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16424* To be passed by HDD to WDA and called upon receiving of response
16425* from firmware
16426* @fwMemDumpReqContext : memory dump request context
16427* @dump_rsp : dump response from HAL
16428* Returns none
16429*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016430void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016431 tAniFwrDumpRsp *dump_rsp)
16432{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016433 struct hdd_request *request;
16434 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016435
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016436 request = hdd_request_get(context);
16437 if (!request) {
16438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16439 return;
16440 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016441
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016442 ENTER();
16443
16444 priv = hdd_request_priv(request);
16445 priv->status = dump_rsp->dump_status;
16446
16447 /* report the status to requesting function and free mem.*/
16448 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16449 hddLog(LOGE, FL("fw dump request declined by fwr"));
16450 //set the request completion variable
16451 hdd_request_complete(request);
16452 //Free the allocated fwr dump
16453 wlan_free_fwr_mem_dump_buffer();
16454 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16455 } else {
16456 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16457 /* register the HDD callback which will be called by SVC */
16458 wlan_set_svc_fw_mem_dump_req_cb(
16459 (void*)wlan_hdd_fw_mem_dump_req_cb,
16460 context);
16461 }
16462
16463 hdd_request_put(request);
16464
16465 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016466}
16467
16468/**
16469 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16470 *
16471 * This function removes file/dir under proc file system that was
16472 * processing firmware memory dump
16473 *
16474 * Return: None
16475 */
16476static void memdump_procfs_remove(void)
16477{
16478 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16479 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16480 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16481 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16482 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16483}
16484
16485/**
16486 * memdump_procfs_init() - Initialize procfs for memory dump
16487 *
16488 * @vos_ctx - Global vos context.
16489 *
16490 * This function create file under proc file system to be used later for
16491 * processing firmware memory dump
16492 *
16493 * Return: 0 on success, error code otherwise.
16494 */
16495static int memdump_procfs_init(void *vos_ctx)
16496{
16497 hdd_context_t *hdd_ctx;
16498
16499 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16500 if (!hdd_ctx) {
16501 hddLog(LOGE , FL("Invalid HDD context"));
16502 return -EINVAL;
16503 }
16504
16505 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16506 if (proc_dir == NULL) {
16507 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16508 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16509 PROCFS_MEMDUMP_DIR);
16510 return -ENOMEM;
16511 }
16512
16513 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16514 S_IRUSR | S_IWUSR, proc_dir,
16515 &memdump_fops, hdd_ctx);
16516 if (proc_file == NULL) {
16517 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16518 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16519 PROCFS_MEMDUMP_NAME);
16520 return -ENOMEM;
16521 }
16522
16523 hddLog(LOG1 , FL("/proc/%s/%s created"),
16524 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16525
16526 return 0;
16527}
16528
16529/**
16530 * memdump_init() - Initialization function for memory dump feature
16531 *
16532 * This function creates proc file for memdump feature and registers
16533 * HDD callback function with SME.
16534 *
16535 * Return - 0 on success, error otherwise
16536 */
16537int memdump_init(void)
16538{
16539 hdd_context_t *hdd_ctx;
16540 void *vos_ctx;
16541 int status = 0;
16542
16543 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16544 if (!vos_ctx) {
16545 hddLog(LOGE, FL("Invalid VOS context"));
16546 return -EINVAL;
16547 }
16548
16549 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16550 if (!hdd_ctx) {
16551 hddLog(LOGE , FL("Invalid HDD context"));
16552 return -EINVAL;
16553 }
16554
16555 status = memdump_procfs_init(vos_ctx);
16556 if (status) {
16557 hddLog(LOGE , FL("Failed to create proc file"));
16558 return status;
16559 }
16560
16561 return 0;
16562}
16563
16564/**
16565 * memdump_deinit() - De initialize memdump feature
16566 *
16567 * This function removes proc file created for memdump feature.
16568 *
16569 * Return: None
16570 */
16571int memdump_deinit(void)
16572{
16573 hdd_context_t *hdd_ctx;
16574 void *vos_ctx;
16575
16576 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16577 if (!vos_ctx) {
16578 hddLog(LOGE, FL("Invalid VOS context"));
16579 return -EINVAL;
16580 }
16581
16582 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16583 if(!hdd_ctx) {
16584 hddLog(LOGE , FL("Invalid HDD context"));
16585 return -EINVAL;
16586 }
16587
16588 memdump_procfs_remove();
16589 return 0;
16590}
16591
16592/**
16593 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16594 * Return: HAL status
16595 */
16596
16597int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16598{
16599 tAniFwrDumpReq fw_mem_dump_req={0};
16600 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016601 int ret=0, dump_status;
16602 void *cookie;
16603 struct hdd_request *request;
16604 struct fw_mem_dump_priv *priv;
16605 static const struct hdd_request_params params = {
16606 .priv_size = sizeof(*priv),
16607 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16608 };
16609
c_manjeecfd1efb2015-09-25 19:32:34 +053016610 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016611
c_manjeecfd1efb2015-09-25 19:32:34 +053016612 /*Check whether a dump request is already going on
16613 *Caution this function will free previously held memory if new dump request is allowed*/
16614 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16615 hddLog(LOGE, FL("Fw memdump already in progress"));
16616 return -EBUSY;
16617 }
16618 //Allocate memory for fw mem dump buffer
16619 ret = wlan_fwr_mem_dump_buffer_allocation();
16620 if(ret == -EFAULT)
16621 {
16622 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16623 return ret;
16624 }
16625 if (0 != ret) {
16626 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16627 return -ENOMEM;
16628 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016629
16630 request = hdd_request_alloc(&params);
16631 if (!request) {
16632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16633 return VOS_STATUS_E_NOMEM;
16634 }
16635 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016636
c_manjeecfd1efb2015-09-25 19:32:34 +053016637 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016638 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016639 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16640 if(eHAL_STATUS_SUCCESS != status)
16641 {
16642 hddLog(VOS_TRACE_LEVEL_ERROR,
16643 "%s: fw_mem_dump_req failed ", __func__);
16644 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016645 ret = -EFAULT;
16646 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016647 }
c_manjeef1495642015-10-13 18:35:01 +053016648 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016649 ret = hdd_request_wait_for_response(request);
16650 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016651 {
16652 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016653 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016654 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016655 }else {
16656 priv = hdd_request_priv(request);
16657 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016658 }
16659cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016660 hdd_request_put(request);
16661 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016662 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016663
c_manjeef1495642015-10-13 18:35:01 +053016664 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016665 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016666}
16667
16668/**
16669 * HDD callback which will be called by SVC to indicate mem dump completion.
16670 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016671void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016672{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016673 struct hdd_request *request;
16674 struct fw_mem_dump_priv *priv;
16675
16676 request = hdd_request_get(context);
16677 if (!request) {
16678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16679 return;
16680 }
16681
16682 priv = hdd_request_priv(request);
16683 priv->status = true;
16684
16685 hdd_request_complete(request);
16686 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016687}
16688
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016689void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16690{
16691 if (NULL == pAdapter)
16692 {
16693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16694 return;
16695 }
16696 init_completion(&pAdapter->session_open_comp_var);
16697 init_completion(&pAdapter->session_close_comp_var);
16698 init_completion(&pAdapter->disconnect_comp_var);
16699 init_completion(&pAdapter->linkup_event_var);
16700 init_completion(&pAdapter->cancel_rem_on_chan_var);
16701 init_completion(&pAdapter->rem_on_chan_ready_event);
16702 init_completion(&pAdapter->pno_comp_var);
16703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16704 init_completion(&pAdapter->offchannel_tx_event);
16705#endif
16706 init_completion(&pAdapter->tx_action_cnf_event);
16707#ifdef FEATURE_WLAN_TDLS
16708 init_completion(&pAdapter->tdls_add_station_comp);
16709 init_completion(&pAdapter->tdls_del_station_comp);
16710 init_completion(&pAdapter->tdls_mgmt_comp);
16711 init_completion(&pAdapter->tdls_link_establish_req_comp);
16712#endif
16713
16714#ifdef WLAN_FEATURE_RMC
16715 init_completion(&pAdapter->ibss_peer_info_comp);
16716#endif /* WLAN_FEATURE_RMC */
16717 init_completion(&pAdapter->ula_complete);
16718 init_completion(&pAdapter->change_country_code);
16719
16720#ifdef FEATURE_WLAN_BATCH_SCAN
16721 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16722 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16723#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016724 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016725
16726 return;
16727}
c_manjeecfd1efb2015-09-25 19:32:34 +053016728
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016729#ifdef MDNS_OFFLOAD
16730
16731/**
16732 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16733 * @padapter: holds adapter
16734 * @status: response status
16735 *
16736 * Return - None
16737 */
16738void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16739{
16740 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16741
16742 ENTER();
16743
16744 if (NULL == adapter)
16745 {
16746 hddLog(VOS_TRACE_LEVEL_ERROR,
16747 "%s: adapter is NULL",__func__);
16748 return;
16749 }
16750
16751 adapter->mdns_status.mdns_enable_status = status;
16752 vos_event_set(&adapter->mdns_status.vos_event);
16753 return;
16754}
16755
16756/**
16757 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16758 * @padapter: holds adapter
16759 * @status: responce status
16760 *
16761 * Return - None
16762 */
16763void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16764{
16765 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16766
16767 ENTER();
16768
16769 if (NULL == adapter)
16770 {
16771 hddLog(VOS_TRACE_LEVEL_ERROR,
16772 "%s: adapter is NULL",__func__);
16773 return;
16774 }
16775
16776 adapter->mdns_status.mdns_fqdn_status = status;
16777 return;
16778}
16779
16780/**
16781 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16782 * @padapter: holds adapter
16783 * @status: responce status
16784 *
16785 * Return - None
16786 */
16787void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16788{
16789 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16790
16791 ENTER();
16792
16793 if (NULL == adapter)
16794 {
16795 hddLog(VOS_TRACE_LEVEL_ERROR,
16796 "%s: adapter is NULL",__func__);
16797 return;
16798 }
16799
16800 adapter->mdns_status.mdns_resp_status = status;
16801 return;
16802}
16803
16804/**
16805 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16806 * @response: Pointer to a struct hdd_mdns_resp_info
16807 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16808 *
16809 * This function will pack the whole domain name without compression. It will
16810 * add the leading len for each field and add zero length octet to terminate
16811 * the domain name.
16812 *
16813 * Return: Return boolean. TRUE for success, FALSE for fail.
16814 */
16815static bool
16816wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16817 sir_mdns_resp_info resp_info)
16818{
16819 uint8_t num;
16820 uint16_t idx;
16821 uint8_t len = 0;
16822
16823 if ((response == NULL) || (response->data == NULL) ||
16824 (response->offset == NULL)) {
16825 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16826 return FALSE;
16827 }
16828
16829 if ((resp_info == NULL) ||
16830 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16831 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16832 return FALSE;
16833 }
16834
16835 for (num = 0; num < response->num_entries; num++) {
16836 response->offset[num] =
16837 resp_info->resp_len + MDNS_HEADER_LEN;
16838 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16839 len = strlen((char *)&response->data[idx]);
16840 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16841 hddLog(LOGE, FL("resp_len exceeds %d!"),
16842 MAX_MDNS_RESP_LEN);
16843 return FALSE;
16844 }
16845 resp_info->resp_data[resp_info->resp_len] = len;
16846 resp_info->resp_len++;
16847 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16848 &response->data[idx], len);
16849 resp_info->resp_len += len;
16850 }
16851
16852 /* The domain name terminates with the zero length octet */
16853 if (num == response->num_entries) {
16854 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16855 hddLog(LOGE, FL("resp_len exceeds %d!"),
16856 MAX_MDNS_RESP_LEN);
16857 return FALSE;
16858 }
16859 resp_info->resp_data[resp_info->resp_len] = 0;
16860 resp_info->resp_len++;
16861 }
16862
16863 return TRUE;
16864}
16865
16866/**
16867 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16868 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16869 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16870 *
16871 * Return: None
16872 */
16873static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16874 sir_mdns_resp_info resp_info)
16875{
16876 uint8_t val_u8;
16877
16878 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16879 return;
16880 val_u8 = (value & 0xff00) >> 8;
16881 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16882 val_u8 = value & 0xff;
16883 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16884}
16885
16886/**
16887 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16888 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16889 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16890 *
16891 * Return: None
16892 */
16893static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16894 sir_mdns_resp_info resp_info)
16895{
16896 uint8_t val_u8;
16897
16898 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16899 return;
16900 val_u8 = (value & 0xff000000) >> 24;
16901 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16902 val_u8 = (value & 0xff0000) >> 16;
16903 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16904 val_u8 = (value & 0xff00) >> 8;
16905 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16906 val_u8 = value & 0xff;
16907 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16908}
16909
16910/**
16911 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16912 * @resp_type: Response type for mDNS
16913 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16914 *
16915 * This function will pack the response type, class and TTL (Time To Live).
16916 *
16917 * Return: Return boolean. TRUE for success, FALSE for fail.
16918 */
16919static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16920 sir_mdns_resp_info resp_info)
16921{
16922 uint16_t len;
16923
16924 if (resp_info == NULL) {
16925 hddLog(LOGE, FL("resp_info is NULL!"));
16926 return FALSE;
16927 }
16928
16929 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16930 if (len >= MAX_MDNS_RESP_LEN) {
16931 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16932 return FALSE;
16933 }
16934
16935 /* Fill Type, Class, TTL */
16936 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16937 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16938 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16939
16940 return TRUE;
16941}
16942
16943/**
16944 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16945 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16946 * @response_dst: The response which domain name is compressed.
16947 * @response_src: The response which domain name is matched with response_dst.
16948 * Its offset is used for data compression.
16949 * @num_matched: The number of matched entries between response_dst and
16950 * response_src
16951 *
16952 * This function will form the different fields of domain name in response_dst
16953 * if any. Then use the offset of the matched domain name in response_src to
16954 * compress the matched domain name.
16955 *
16956 * Return: Return boolean. TRUE for success, FALSE for fail.
16957 */
16958static bool
16959wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16960 struct hdd_mdns_resp_info *response_dst,
16961 struct hdd_mdns_resp_info *response_src,
16962 uint8_t num_matched)
16963{
16964 uint8_t num, num_diff;
16965 uint16_t value, idx;
16966 uint8_t len = 0;
16967
16968 if ((response_src == NULL) || (response_dst == NULL) ||
16969 (resp_info == NULL)) {
16970 hddLog(LOGE, FL("response info is NULL!"));
16971 return FALSE;
16972 }
16973
16974 if (response_dst->num_entries < num_matched) {
16975 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16976 return FALSE;
16977 }
16978
16979 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16980 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16981 return FALSE;
16982 }
16983
16984 num_diff = response_dst->num_entries - num_matched;
16985 if ((num_diff > 0) && (response_dst->data == NULL)) {
16986 hddLog(LOGE, FL("response_dst->data is NULL!"));
16987 return FALSE;
16988 }
16989
16990 /*
16991 * Handle the unmatched string at the beginning
16992 * Store the length of octets and the octets
16993 */
16994 for (num = 0; num < num_diff; num++) {
16995 response_dst->offset[num] =
16996 resp_info->resp_len + MDNS_HEADER_LEN;
16997 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16998 len = strlen((char *)&response_dst->data[idx]);
16999 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
17000 hddLog(LOGE, FL("resp_len exceeds %d!"),
17001 MAX_MDNS_RESP_LEN);
17002 return FALSE;
17003 }
17004 resp_info->resp_data[resp_info->resp_len] = len;
17005 resp_info->resp_len++;
17006 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17007 &response_dst->data[idx], len);
17008 resp_info->resp_len += len;
17009 }
17010 /*
17011 * Handle the matched string from the end
17012 * Just keep the offset and mask the leading two bit
17013 */
17014 if (response_src->num_entries >= num_matched) {
17015 num_diff = response_src->num_entries - num_matched;
17016 value = response_src->offset[num_diff];
17017 if (value > 0) {
17018 value |= 0xc000;
17019 if ((resp_info->resp_len + sizeof(uint16_t)) >=
17020 MAX_MDNS_RESP_LEN) {
17021 hddLog(LOGE, FL("resp_len exceeds %d!"),
17022 MAX_MDNS_RESP_LEN);
17023 return FALSE;
17024 }
17025 wlan_hdd_mdns_format_response_u16(value, resp_info);
17026 return TRUE;
17027 }
17028 }
17029 return FALSE;
17030}
17031
17032/**
17033 * wlan_hdd_mdns_reset_response() - Reset the response info
17034 * @response: The response which info is reset.
17035 *
17036 * Return: None
17037 */
17038static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
17039{
17040 if (response == NULL)
17041 return;
17042 response->num_entries = 0;
17043 response->data = NULL;
17044 response->offset = NULL;
17045}
17046
17047/**
17048 * wlan_hdd_mdns_init_response() - Initialize the response info
17049 * @response: The response which info is initiatized.
17050 * @resp_dname: The domain name string which might be tokenized.
17051 *
17052 * This function will allocate the memory for both response->data and
17053 * response->offset. Besides, it will also tokenize the domain name to some
17054 * entries and fill response->num_entries with the num of entries.
17055 *
17056 * Return: Return boolean. TRUE for success, FALSE for fail.
17057 */
17058static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
17059 uint8_t *resp_dname, char separator)
17060{
17061 uint16_t size;
17062
17063 if ((resp_dname == NULL) || (response == NULL)) {
17064 hddLog(LOGE, FL("resp_dname or response is NULL!"));
17065 return FALSE;
17066 }
17067
17068 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
17069 response->data = vos_mem_malloc(size);
17070 if (response->data) {
17071 vos_mem_zero(response->data, size);
17072 if (VOS_STATUS_SUCCESS !=
17073 hdd_string_to_string_array((char *)resp_dname,
17074 response->data,
17075 separator,
17076 &response->num_entries,
17077 MAX_NUM_FIELD_DOMAINNAME,
17078 MAX_LEN_DOMAINNAME_FIELD)) {
17079 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
17080 goto err_init_resp;
17081 }
17082
17083 if ((response->num_entries > 0) &&
17084 (strlen((char *)&response->data[0]) > 0)) {
17085 size = sizeof(uint16_t) * response->num_entries;
17086 response->offset = vos_mem_malloc(size);
17087 if (response->offset) {
17088 vos_mem_zero(response->offset, size);
17089 return TRUE;
17090 }
17091 }
17092 }
17093
17094err_init_resp:
17095 if (response->data)
17096 vos_mem_free(response->data);
17097 wlan_hdd_mdns_reset_response(response);
17098 return FALSE;
17099}
17100
17101/**
17102 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
17103 * @response1: The response info is used to be compared.
17104 * @response2: The response info is used to be compared.
17105 *
17106 * This function will find the matched entries from the end.
17107 *
17108 * Return: Return the number of the matched entries.
17109 */
17110static uint8_t
17111wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
17112 struct hdd_mdns_resp_info *response2)
17113{
17114 uint8_t min, len1, i;
17115 uint16_t num1, num2;
17116 uint8_t num_matched = 0;
17117
17118 min = VOS_MIN(response1->num_entries, response2->num_entries);
17119
17120 for (i = 1; i <= min; i++) {
17121 num1 = (response1->num_entries - i);
17122 num1 *= MAX_LEN_DOMAINNAME_FIELD;
17123 num2 = (response2->num_entries - i);
17124 num2 *= MAX_LEN_DOMAINNAME_FIELD;
17125 len1 = strlen((char *)&response1->data[num1]);
17126
17127 if ((len1 == 0) ||
17128 (len1 != strlen((char *)&response2->data[num2])))
17129 break;
17130 if (memcmp(&response1->data[num1],
17131 &response2->data[num2], len1))
17132 break;
17133 else
17134 num_matched++;
17135 }
17136
17137 return num_matched;
17138}
17139
17140/**
17141 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17142 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17143 * @numlist: The number of the elements in the array matchedlist.
17144 *
17145 * Find the max number of the matched entries among the array matchedlist.
17146 *
17147 * Return: None
17148 */
17149static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17150 uint8_t numlist)
17151{
17152 int j;
17153 struct hdd_mdns_resp_matched tmp;
17154
17155 /* At least two values are used for sorting */
17156 if ((numlist < 2) || (matchedlist == NULL)) {
17157 hddLog(LOGE, FL("At least two values are used for sorting!"));
17158 return;
17159 }
17160
17161 for (j = 0; j < numlist-1; j++) {
17162 if (matchedlist[j].num_matched >
17163 matchedlist[j+1].num_matched) {
17164 vos_mem_copy(&tmp, &matchedlist[j],
17165 sizeof(struct hdd_mdns_resp_matched));
17166 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17167 sizeof(struct hdd_mdns_resp_matched));
17168 vos_mem_copy(&matchedlist[j+1], &tmp,
17169 sizeof(struct hdd_mdns_resp_matched));
17170 }
17171 }
17172}
17173
17174/**
17175 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17176 * @ini_config: Pointer to the struct hdd_config_t
17177 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17178 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17179 *
17180 * Type A response include QName, response type, class, TTL and Ipv4.
17181 *
17182 * Return: Return boolean. TRUE for success, FALSE for fail.
17183 */
17184static bool
17185wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17186 sir_mdns_resp_info resp_info,
17187 struct hdd_mdns_resp_info *resptype_a)
17188{
17189 uint16_t value;
17190 uint32_t len;
17191
17192 ENTER();
17193 if ((ini_config == NULL) || (resp_info == NULL) ||
17194 (resptype_a == NULL)) {
17195 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17196 return FALSE;
17197 }
17198
17199 /* No Type A response */
17200 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17201 return TRUE;
17202
17203 /* Wrong response is assigned, just ignore this response */
17204 if (!wlan_hdd_mdns_init_response(resptype_a,
17205 ini_config->mdns_resp_type_a, '.'))
17206 return TRUE;
17207
17208 /* Process response domain name */
17209 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17210 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17211 MDNS_TYPE_A);
17212 return FALSE;
17213 }
17214
17215 /* Process response Type, Class, TTL */
17216 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17217 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17218 MDNS_TYPE_A);
17219 return FALSE;
17220 }
17221
17222 /* Process response RDLength, RData */
17223 len = sizeof(uint16_t) + sizeof(uint32_t);
17224 len += resp_info->resp_len;
17225 if (len >= MAX_MDNS_RESP_LEN) {
17226 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17227 return FALSE;
17228 }
17229 value = sizeof(uint32_t);
17230 wlan_hdd_mdns_format_response_u16(value, resp_info);
17231 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17232 resp_info);
17233
17234 EXIT();
17235 return TRUE;
17236}
17237
17238/**
17239 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17240 * @ini_config: Pointer to the struct hdd_config_t
17241 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17242 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17243 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17244 *
17245 * Type Txt response include QName, response type, class, TTL and text content.
17246 * Also, it will find the matched QName from resptype_A and compress the data.
17247 *
17248 * Return: Return boolean. TRUE for success, FALSE for fail.
17249 */
17250static bool
17251wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17252 sir_mdns_resp_info resp_info,
17253 struct hdd_mdns_resp_info *resptype_txt,
17254 struct hdd_mdns_resp_info *resptype_a)
17255{
17256 uint8_t num_matched;
17257 uint8_t num;
17258 uint16_t idx;
17259 uint16_t value = 0;
17260 uint32_t len;
17261 uint32_t total_len;
17262 bool status;
17263 struct hdd_mdns_resp_info resptype_content;
17264
17265 ENTER();
17266
17267 if ((ini_config == NULL) || (resp_info == NULL) ||
17268 (resptype_txt == NULL)) {
17269 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17270 return FALSE;
17271 }
17272
17273 /* No Type Txt response */
17274 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17275 return TRUE;
17276
17277 /* Wrong response is assigned, just ignore this response */
17278 if (!wlan_hdd_mdns_init_response(resptype_txt,
17279 ini_config->mdns_resp_type_txt, '.'))
17280 return TRUE;
17281
17282 /*
17283 * For data compression
17284 * Check if any strings are matched with Type A response
17285 */
17286 if (resptype_a && (resptype_a->num_entries > 0)) {
17287 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17288 resptype_a);
17289 if (num_matched > 0) {
17290 if (!wlan_hdd_mdns_compress_data(resp_info,
17291 resptype_txt, resptype_a, num_matched)) {
17292 hddLog(LOGE, FL("Fail to compress mDNS "
17293 "response (%d)!"), MDNS_TYPE_TXT);
17294 return FALSE;
17295 }
17296 } else {
17297 /*
17298 * num_matched is zero. Error!
17299 * At least ".local" is needed.
17300 */
17301 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17302 "response (%d)!"), MDNS_TYPE_TXT);
17303 return FALSE;
17304 }
17305 } else {
17306 /* no TypeA response, so show the whole data */
17307 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17308 resp_info)) {
17309 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17310 MDNS_TYPE_TXT);
17311 return FALSE;
17312 }
17313 }
17314
17315 /* Process response Type, Class, TTL */
17316 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17317 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17318 MDNS_TYPE_TXT);
17319 return FALSE;
17320 }
17321
17322 /*
17323 * Process response RDLength, RData.
17324 * TypeTxt RData include len.
17325 */
17326 status = wlan_hdd_mdns_init_response(&resptype_content,
17327 ini_config->mdns_resp_type_txt_content,
17328 '/');
17329 if (status == FALSE) {
17330 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17331 return FALSE;
17332 }
17333
17334 for (num = 0; num < resptype_content.num_entries; num++) {
17335 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17336 value += strlen((char *)&resptype_content.data[idx]);
17337 }
17338
17339 /* content len is uint16_t */
17340 total_len = sizeof(uint16_t);
17341 total_len += resp_info->resp_len + value +
17342 resptype_content.num_entries;
17343
17344 if (total_len >= MAX_MDNS_RESP_LEN) {
17345 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17346 return FALSE;
17347 }
17348 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17349 resp_info);
17350
17351 for (num = 0; num < resptype_content.num_entries; num++) {
17352 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17353 len = strlen((char *)&resptype_content.data[idx]);
17354 resp_info->resp_data[resp_info->resp_len] = len;
17355 resp_info->resp_len++;
17356
17357 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17358 &resptype_content.data[idx], len);
17359
17360 resp_info->resp_len += len;
17361 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17362 num, len, &resptype_content.data[idx]);
17363 }
17364
17365 EXIT();
17366 return TRUE;
17367}
17368
17369/**
17370 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17371 * @ini_config: Pointer to the struct hdd_config_t
17372 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17373 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17374 * domain name
17375 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17376 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17377 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17378 *
17379 * The Type Ptr response include Type PTR domain name in its data field.
17380 * Also, it will find the matched QName from the existing resptype_ptr,
17381 * resptype_txt, resptype_a and then compress the data.
17382 *
17383 * Return: Return boolean. TRUE for success, FALSE for fail.
17384 */
17385static bool
17386wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17387 sir_mdns_resp_info resp_info,
17388 struct hdd_mdns_resp_info *resptype_ptr_dn,
17389 struct hdd_mdns_resp_info *resptype_ptr,
17390 struct hdd_mdns_resp_info *resptype_txt,
17391 struct hdd_mdns_resp_info *resptype_a)
17392{
17393 uint8_t num_matched, numlist, size;
17394 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17395 struct hdd_mdns_resp_info *resp;
17396
17397 if ((ini_config == NULL) || (resp_info == NULL) ||
17398 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17399 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17400 return FALSE;
17401 }
17402
17403 /* No Type Ptr domain name response */
17404 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17405 return TRUE;
17406
17407 /* Wrong response is assigned, just ignore this response */
17408 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17409 ini_config->mdns_resp_type_ptr_dname, '.'))
17410 return TRUE;
17411
17412 /*
17413 * For data compression
17414 * Check if any strings are matched with previous
17415 * response.
17416 */
17417 numlist = 0;
17418 size = (MAX_MDNS_RESP_TYPE-1);
17419 size *= sizeof(struct hdd_mdns_resp_matched);
17420 vos_mem_zero(matchedlist, size);
17421 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17422 resptype_ptr);
17423 if (num_matched > 0) {
17424 matchedlist[numlist].num_matched = num_matched;
17425 matchedlist[numlist].type = MDNS_TYPE_PTR;
17426 numlist++;
17427 }
17428 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17429 num_matched = wlan_hdd_mdns_find_entries_from_end(
17430 resptype_ptr_dn, resptype_txt);
17431 if (num_matched > 0) {
17432 matchedlist[numlist].num_matched = num_matched;
17433 matchedlist[numlist].type = MDNS_TYPE_TXT;
17434 numlist++;
17435 }
17436 }
17437 if (resptype_a && (resptype_a->num_entries > 0)) {
17438 num_matched = wlan_hdd_mdns_find_entries_from_end(
17439 resptype_ptr_dn,resptype_a);
17440 if (num_matched > 0) {
17441 matchedlist[numlist].num_matched = num_matched;
17442 matchedlist[numlist].type = MDNS_TYPE_A;
17443 numlist++;
17444 }
17445 }
17446 if (numlist > 0) {
17447 if (numlist > 1)
17448 wlan_hdd_mdns_find_max(matchedlist, numlist);
17449 resp = NULL;
17450 switch (matchedlist[numlist-1].type) {
17451 case MDNS_TYPE_A:
17452 resp = resptype_a;
17453 break;
17454 case MDNS_TYPE_TXT:
17455 resp = resptype_txt;
17456 break;
17457 case MDNS_TYPE_PTR:
17458 resp = resptype_ptr;
17459 break;
17460 default:
17461 hddLog(LOGE, FL("Fail to compress mDNS response "
17462 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17463 return FALSE;
17464 }
17465 num_matched = matchedlist[numlist-1].num_matched;
17466 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17467 resp, num_matched)) {
17468 hddLog(LOGE, FL("Fail to compress mDNS response "
17469 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17470 return FALSE;
17471 }
17472 } else {
17473 /* num = 0 -> no matched string */
17474 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17475 resp_info)) {
17476 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17477 MDNS_TYPE_PTR_DNAME);
17478 return FALSE;
17479 }
17480 }
17481
17482 return TRUE;
17483}
17484
17485/**
17486 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17487 * @ini_config: Pointer to the struct hdd_config_t
17488 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17489 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17490 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17491 * domain name
17492 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17493 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17494 *
17495 * The Type Ptr response include QName, response type, class, TTL and
17496 * Type PTR domain name. Also, it will find the matched QName from the
17497 * existing resptype_txt, resptype_a and then compress the data.
17498 *
17499 * Return: Return boolean. TRUE for success, FALSE for fail.
17500 */
17501static bool
17502wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17503 sir_mdns_resp_info resp_info,
17504 struct hdd_mdns_resp_info *resptype_ptr,
17505 struct hdd_mdns_resp_info *resptype_ptr_dn,
17506 struct hdd_mdns_resp_info *resptype_txt,
17507 struct hdd_mdns_resp_info *resptype_a)
17508{
17509 uint8_t num_matched, num_matched1;
17510 uint16_t value;
17511 uint8_t val_u8;
17512 uint32_t offset_data_len, len;
17513
17514 ENTER();
17515 if ((ini_config == NULL) || (resp_info == NULL) ||
17516 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17517 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17518 return FALSE;
17519 }
17520
17521 /* No Type Ptr response */
17522 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17523 return TRUE;
17524
17525 /* Wrong response is assigned, just ignore this response */
17526 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17527 ini_config->mdns_resp_type_ptr, '.'))
17528 return TRUE;
17529
17530 /*
17531 * For data compression
17532 * Check if any strings are matched with Type A response
17533 */
17534 num_matched = 0;
17535 num_matched1 = 0;
17536 if (resptype_a && (resptype_a->num_entries > 0)) {
17537 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17538 resptype_a);
17539 }
17540 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17541 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17542 resptype_ptr, resptype_txt);
17543 }
17544 if ((num_matched != num_matched1) ||
17545 ((num_matched > 0) && (num_matched1 > 0))) {
17546 if (num_matched >= num_matched1) {
17547 if (!wlan_hdd_mdns_compress_data(resp_info,
17548 resptype_ptr, resptype_a, num_matched)) {
17549 hddLog(LOGE, FL("Fail to compress mDNS "
17550 "response (%d)!"), MDNS_TYPE_PTR);
17551 return FALSE;
17552 }
17553 } else {
17554 /* num_matched is less than num_matched1 */
17555 if (!wlan_hdd_mdns_compress_data(resp_info,
17556 resptype_ptr, resptype_txt, num_matched1)) {
17557 hddLog(LOGE, FL("Fail to compress mDNS "
17558 "response (%d)!"), MDNS_TYPE_PTR);
17559 return FALSE;
17560 }
17561 }
17562 } else {
17563 /*
17564 * Both num_matched and num_matched1 are zero.
17565 * no TypeA & TypeTxt
17566 */
17567 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17568 resp_info)) {
17569 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17570 MDNS_TYPE_PTR);
17571 return FALSE;
17572 }
17573 }
17574
17575 /* Process response Type, Class, TTL */
17576 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17577 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17578 MDNS_TYPE_PTR);
17579 return FALSE;
17580 }
17581
17582 /*
17583 * Process response RDLength, RData (Ptr domain name)
17584 * Save the offset of RData length
17585 */
17586 offset_data_len = resp_info->resp_len;
17587 resp_info->resp_len += sizeof(uint16_t);
17588
17589 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17590 resptype_ptr_dn, resptype_ptr,
17591 resptype_txt, resptype_a)) {
17592 return FALSE;
17593 }
17594 /* Set the RData length */
17595 len = offset_data_len + sizeof(uint16_t);
17596 if ((resptype_ptr_dn->num_entries > 0) &&
17597 (resp_info->resp_len > len)) {
17598 value = resp_info->resp_len - len;
17599 val_u8 = (value & 0xff00) >> 8;
17600 resp_info->resp_data[offset_data_len] = val_u8;
17601 val_u8 = value & 0xff;
17602 resp_info->resp_data[offset_data_len+1] = val_u8;
17603 } else {
17604 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17605 MDNS_TYPE_PTR);
17606 return FALSE;
17607 }
17608
17609 EXIT();
17610 return TRUE;
17611}
17612
17613/**
17614 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17615 * @ini_config: Pointer to the struct hdd_config_t
17616 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17617 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17618 * target
17619 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17620 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17621 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17622 * domain name
17623 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17624 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17625 *
17626 * The Type service target is one of the data field in the Type SRV response.
17627 * Also, it will find the matched QName from the existing resptype_srv,
17628 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17629 * the data.
17630 *
17631 * Return: Return boolean. TRUE for success, FALSE for fail.
17632 */
17633static bool
17634wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17635 sir_mdns_resp_info resp_info,
17636 struct hdd_mdns_resp_info *resptype_srv_tgt,
17637 struct hdd_mdns_resp_info *resptype_srv,
17638 struct hdd_mdns_resp_info *resptype_ptr,
17639 struct hdd_mdns_resp_info *resptype_ptr_dn,
17640 struct hdd_mdns_resp_info *resptype_txt,
17641 struct hdd_mdns_resp_info *resptype_a)
17642{
17643 uint8_t num_matched, num, size;
17644 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17645 struct hdd_mdns_resp_info *resp;
17646
17647 if ((ini_config == NULL) || (resp_info == NULL) ||
17648 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17649 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17650 return FALSE;
17651 }
17652
17653 /* No Type Srv Target response */
17654 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17655 return TRUE;
17656
17657 /* Wrong response is assigned, just ignore this response */
17658 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17659 ini_config->mdns_resp_type_srv_target, '.'))
17660 return TRUE;
17661
17662 /*
17663 * For data compression
17664 * Check if any strings are matched with previous response.
17665 */
17666 num = 0;
17667 size = (MAX_MDNS_RESP_TYPE-1);
17668 size *= sizeof(struct hdd_mdns_resp_matched);
17669 vos_mem_zero(matchedlist, size);
17670 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17671 resptype_srv);
17672 if (num_matched > 0) {
17673 matchedlist[num].num_matched = num_matched;
17674 matchedlist[num].type = MDNS_TYPE_SRV;
17675 num++;
17676 }
17677 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17678 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17679 num_matched = wlan_hdd_mdns_find_entries_from_end(
17680 resptype_srv_tgt, resptype_ptr_dn);
17681 if (num_matched > 0) {
17682 matchedlist[num].num_matched = num_matched;
17683 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17684 num++;
17685 }
17686 }
17687 num_matched = wlan_hdd_mdns_find_entries_from_end(
17688 resptype_srv_tgt, resptype_ptr);
17689 if (num_matched > 0) {
17690 matchedlist[num].num_matched = num_matched;
17691 matchedlist[num].type = MDNS_TYPE_PTR;
17692 num++;
17693 }
17694 }
17695 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17696 num_matched = wlan_hdd_mdns_find_entries_from_end(
17697 resptype_srv_tgt, resptype_txt);
17698 if (num_matched > 0) {
17699 matchedlist[num].num_matched = num_matched;
17700 matchedlist[num].type = MDNS_TYPE_TXT;
17701 num++;
17702 }
17703 }
17704 if (resptype_a && (resptype_a->num_entries > 0)) {
17705 num_matched = wlan_hdd_mdns_find_entries_from_end(
17706 resptype_srv_tgt, resptype_a);
17707 if (num_matched > 0) {
17708 matchedlist[num].num_matched = num_matched;
17709 matchedlist[num].type = MDNS_TYPE_A;
17710 num++;
17711 }
17712 }
17713 if (num > 0) {
17714 if (num > 1)
17715 wlan_hdd_mdns_find_max(matchedlist, num);
17716 resp = NULL;
17717 switch (matchedlist[num-1].type) {
17718 case MDNS_TYPE_A:
17719 resp = resptype_a;
17720 break;
17721 case MDNS_TYPE_TXT:
17722 resp = resptype_txt;
17723 break;
17724 case MDNS_TYPE_PTR:
17725 resp = resptype_ptr;
17726 break;
17727 case MDNS_TYPE_PTR_DNAME:
17728 resp = resptype_ptr_dn;
17729 break;
17730 case MDNS_TYPE_SRV:
17731 resp = resptype_srv;
17732 break;
17733 default:
17734 hddLog(LOGE, FL("Fail to compress mDNS response "
17735 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17736 return FALSE;
17737 }
17738 num_matched = matchedlist[num-1].num_matched;
17739 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17740 resp, num_matched)) {
17741 hddLog(LOGE, FL("Fail to compress mDNS response "
17742 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17743 return FALSE;
17744 }
17745 } else {
17746 /* num = 0 -> no matched string */
17747 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17748 resp_info)) {
17749 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17750 MDNS_TYPE_SRV_TARGET);
17751 return FALSE;
17752 }
17753 }
17754
17755 return TRUE;
17756}
17757
17758/**
17759 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17760 * @ini_config: Pointer to the struct hdd_config_t
17761 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17762 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17763 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17764 * target
17765 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17766 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17767 * domain name
17768 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17769 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17770 *
17771 * The Type SRV (Service) response include QName, response type, class, TTL
17772 * and four kinds of data fields. Also, it will find the matched QName from
17773 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17774 * then compress the data.
17775 *
17776 * Return: Return boolean. TRUE for success, FALSE for fail.
17777 */
17778static bool
17779wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17780 sir_mdns_resp_info resp_info,
17781 struct hdd_mdns_resp_info *resptype_srv,
17782 struct hdd_mdns_resp_info *resptype_srv_tgt,
17783 struct hdd_mdns_resp_info *resptype_ptr,
17784 struct hdd_mdns_resp_info *resptype_ptr_dn,
17785 struct hdd_mdns_resp_info *resptype_txt,
17786 struct hdd_mdns_resp_info *resptype_a)
17787{
17788 uint8_t num_matched, num, size;
17789 uint16_t value;
17790 uint8_t val_u8;
17791 uint32_t offset_data_len, len;
17792 struct hdd_mdns_resp_info *resp;
17793 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17794
17795 ENTER();
17796
17797 if ((ini_config == NULL) || (resp_info == NULL) ||
17798 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17799 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17800 return FALSE;
17801 }
17802
17803 /* No Type Srv response */
17804 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17805 return TRUE;
17806
17807 /* Wrong response is assigned, just ignore this response */
17808 if (!wlan_hdd_mdns_init_response(resptype_srv,
17809 ini_config->mdns_resp_type_srv, '.'))
17810 return TRUE;
17811
17812 /*
17813 * For data compression
17814 * Check if any strings are matched with Type A response
17815 */
17816 num = 0;
17817 size = (MAX_MDNS_RESP_TYPE-1);
17818 size *= sizeof(struct hdd_mdns_resp_matched);
17819 vos_mem_zero(matchedlist, size);
17820 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17821 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17822 num_matched = wlan_hdd_mdns_find_entries_from_end(
17823 resptype_srv,
17824 resptype_ptr_dn);
17825 if (num_matched > 0) {
17826 matchedlist[num].num_matched = num_matched;
17827 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17828 num++;
17829 }
17830 }
17831 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17832 resptype_ptr);
17833 if (num_matched > 0) {
17834 matchedlist[num].num_matched = num_matched;
17835 matchedlist[num].type = MDNS_TYPE_PTR;
17836 num++;
17837 }
17838 }
17839 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17840 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17841 resptype_txt);
17842 if (num_matched > 0) {
17843 matchedlist[num].num_matched =num_matched;
17844 matchedlist[num].type = MDNS_TYPE_TXT;
17845 num++;
17846 }
17847 }
17848 if (resptype_a && (resptype_a->num_entries > 0)) {
17849 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17850 resptype_a);
17851 if (num_matched > 0) {
17852 matchedlist[num].num_matched = num_matched;
17853 matchedlist[num].type = MDNS_TYPE_A;
17854 num++;
17855 }
17856 }
17857 if (num > 0) {
17858 if (num > 1)
17859 wlan_hdd_mdns_find_max(matchedlist, num);
17860 resp = NULL;
17861 switch (matchedlist[num-1].type) {
17862 case MDNS_TYPE_A:
17863 resp = resptype_a;
17864 break;
17865 case MDNS_TYPE_TXT:
17866 resp = resptype_txt;
17867 break;
17868 case MDNS_TYPE_PTR:
17869 resp = resptype_ptr;
17870 break;
17871 case MDNS_TYPE_PTR_DNAME:
17872 resp = resptype_ptr_dn;
17873 break;
17874 default:
17875 hddLog(LOGE, FL("Fail to compress mDNS response "
17876 "(%d)!"), MDNS_TYPE_SRV);
17877 return FALSE;
17878 }
17879 num_matched = matchedlist[num-1].num_matched;
17880 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17881 resp, num_matched)) {
17882 hddLog(LOGE, FL("Fail to compress mDNS response "
17883 "(%d)!"), MDNS_TYPE_SRV);
17884 return FALSE;
17885 }
17886 } else {
17887 /* num = 0 -> no matched string */
17888 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17889 resp_info)) {
17890 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17891 MDNS_TYPE_SRV);
17892 return FALSE;
17893 }
17894 }
17895
17896 /* Process response Type, Class, TTL */
17897 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17898 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17899 MDNS_TYPE_SRV);
17900 return FALSE;
17901 }
17902
17903 /*
17904 * Process response RDLength, RData (Srv target name)
17905 * Save the offset of RData length
17906 */
17907 offset_data_len = resp_info->resp_len;
17908 resp_info->resp_len += sizeof(uint16_t);
17909
17910 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17911 if (len >= MAX_MDNS_RESP_LEN) {
17912 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17913 return FALSE;
17914 }
17915
17916 /* set Srv Priority */
17917 value = ini_config->mdns_resp_type_srv_priority;
17918 wlan_hdd_mdns_format_response_u16(value, resp_info);
17919 /* set Srv Weight */
17920 value = ini_config->mdns_resp_type_srv_weight;
17921 wlan_hdd_mdns_format_response_u16(value, resp_info);
17922 /* set Srv Port */
17923 value = ini_config->mdns_resp_type_srv_port;
17924 wlan_hdd_mdns_format_response_u16(value, resp_info);
17925
17926 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17927 resptype_srv_tgt, resptype_srv,
17928 resptype_ptr, resptype_ptr_dn,
17929 resptype_txt, resptype_a)) {
17930 return FALSE;
17931 }
17932 /* Set the RData length */
17933 len = offset_data_len + sizeof(uint16_t);
17934 if ((resptype_srv_tgt->num_entries > 0) &&
17935 (resp_info->resp_len > len)) {
17936 value = resp_info->resp_len - len;
17937 val_u8 = (value & 0xff00) >> 8;
17938 resp_info->resp_data[offset_data_len] = val_u8;
17939 val_u8 = value & 0xff;
17940 resp_info->resp_data[offset_data_len+1] = val_u8;
17941 } else {
17942 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17943 MDNS_TYPE_SRV);
17944 return FALSE;
17945 }
17946
17947 EXIT();
17948 return TRUE;
17949}
17950
17951/**
17952 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17953 * @response: Pointer to the struct hdd_mdns_resp_info
17954 *
17955 * Return: None
17956 */
17957static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17958{
17959 if (response && response->data)
17960 vos_mem_free(response->data);
17961 if (response && response->offset)
17962 vos_mem_free(response->offset);
17963}
17964
17965/**
17966 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17967 * @ini_config: Pointer to the struct hdd_config_t
17968 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17969 *
17970 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17971 * and Type Service). Each response contains QName, response type, class, TTL
17972 * and data fields.
17973 *
17974 * Return: Return boolean. TRUE for success, FALSE for fail.
17975 */
17976static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17977 sir_mdns_resp_info resp_info)
17978{
17979 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17980 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17981 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17982 uint32_t num_res_records = 0;
17983 bool status = FALSE;
17984
17985 ENTER();
17986
17987 wlan_hdd_mdns_reset_response(&resptype_a);
17988 wlan_hdd_mdns_reset_response(&resptype_txt);
17989 wlan_hdd_mdns_reset_response(&resptype_ptr);
17990 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17991 wlan_hdd_mdns_reset_response(&resptype_srv);
17992 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17993
17994 resp_info->resp_len = 0;
17995
17996 /* Process Type A response */
17997 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17998 &resptype_a))
17999 goto err_resptype_a;
18000
18001 if ((resptype_a.num_entries > 0) &&
18002 (strlen((char *)&resptype_a.data[0]) > 0))
18003 num_res_records++;
18004
18005 /* Process Type TXT response */
18006 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
18007 &resptype_txt, &resptype_a))
18008 goto err_resptype_txt;
18009
18010 if ((resptype_txt.num_entries > 0) &&
18011 (strlen((char *)&resptype_txt.data[0]) > 0))
18012 num_res_records++;
18013
18014 /* Process Type PTR response */
18015 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
18016 &resptype_ptr, &resptype_ptr_dn,
18017 &resptype_txt, &resptype_a))
18018 goto err_resptype_ptr;
18019
18020 if ((resptype_ptr.num_entries > 0) &&
18021 (strlen((char *)&resptype_ptr.data[0]) > 0))
18022 num_res_records++;
18023
18024 /* Process Type SRV response */
18025 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
18026 &resptype_srv, &resptype_srv_tgt,
18027 &resptype_ptr, &resptype_ptr_dn,
18028 &resptype_txt, &resptype_a))
18029 goto err_resptype_srv;
18030
18031 if ((resptype_srv.num_entries > 0) &&
18032 (strlen((char *)&resptype_srv.data[0]) > 0))
18033 num_res_records++;
18034
18035 resp_info->resourceRecord_count = num_res_records;
18036 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18037 "%s: Pack mDNS response data successfully!", __func__);
18038 status = TRUE;
18039
18040err_resptype_srv:
18041 wlan_hdd_mdns_free_mem(&resptype_srv);
18042 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
18043
18044err_resptype_ptr:
18045 wlan_hdd_mdns_free_mem(&resptype_ptr);
18046 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
18047
18048err_resptype_txt:
18049 wlan_hdd_mdns_free_mem(&resptype_txt);
18050
18051err_resptype_a:
18052 wlan_hdd_mdns_free_mem(&resptype_a);
18053
18054 EXIT();
18055 return status;
18056}
18057
18058/**
18059 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
18060 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
18061 *
18062 * This function will set FQDN/unique FQDN (full qualified domain name)
18063 * and the mDNS response. Then send them to SME.
18064 *
18065 * Return: Return boolean. TRUE for success, FALSE for fail.
18066 */
18067bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
18068{
18069 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
18070 sir_mdns_offload_info mdns_offload_info;
18071 sir_mdns_fqdn_info mdns_fqdn_info;
18072 sir_mdns_resp_info mdns_resp_info;
18073 uint32_t fqdn_len, ufqdn_len;
18074
18075 ENTER();
18076
18077 /* 1. Prepare the MDNS fqdn request to send to SME */
18078 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
18079 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
18080 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
18081 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
18082 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
18083 return FALSE;
18084 }
18085
18086 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
18087 if (NULL == mdns_fqdn_info) {
18088 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
18089 return FALSE;
18090 }
18091 /* MDNS fqdn request */
18092 if (fqdn_len > 0) {
18093 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18094 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18095 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
18096 mdns_fqdn_info->fqdn_len = fqdn_len;
18097 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18098 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18099 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18100 hdd_ctx->cfg_ini->mdns_fqdn,
18101 mdns_fqdn_info->fqdn_len);
18102
18103 if (eHAL_STATUS_SUCCESS !=
18104 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18105 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18106 vos_mem_free(mdns_fqdn_info);
18107 return FALSE;
18108 }
18109 }
18110 /* MDNS unique fqdn request */
18111 if (ufqdn_len > 0) {
18112 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18113 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18114 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
18115 mdns_fqdn_info->fqdn_len = ufqdn_len;
18116 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18117 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18118 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18119 hdd_ctx->cfg_ini->mdns_uniquefqdn,
18120 mdns_fqdn_info->fqdn_len);
18121 if (eHAL_STATUS_SUCCESS !=
18122 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18123 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18124 vos_mem_free(mdns_fqdn_info);
18125 return FALSE;
18126 }
18127 }
18128 vos_mem_free(mdns_fqdn_info);
18129
18130 /* 2. Prepare the MDNS response request to send to SME */
18131 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18132 if (NULL == mdns_resp_info) {
18133 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18134 return FALSE;
18135 }
18136
18137 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18138 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18139 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18140 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18141 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18142 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18143 vos_mem_free(mdns_resp_info);
18144 return FALSE;
18145 }
18146 if (eHAL_STATUS_SUCCESS !=
18147 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18148 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18149 vos_mem_free(mdns_resp_info);
18150 return FALSE;
18151 }
18152 vos_mem_free(mdns_resp_info);
18153
18154 /* 3. Prepare the MDNS Enable request to send to SME */
18155 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18156 if (NULL == mdns_offload_info) {
18157 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18158 return FALSE;
18159 }
18160
18161 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18162
18163 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18164 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18165 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18166 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18167 if (eHAL_STATUS_SUCCESS !=
18168 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18169 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18170 vos_mem_free(mdns_offload_info);
18171 return FALSE;
18172 }
18173
18174 vos_mem_free(mdns_offload_info);
18175 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18176 "%s: enable mDNS offload successfully!", __func__);
18177 return TRUE;
18178}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018179
18180
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018181#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018182
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018183/**
18184 * wlan_hdd_start_sap() - This function starts bss of SAP.
18185 * @ap_adapter: SAP adapter
18186 *
18187 * This function will process the starting of sap adapter.
18188 *
18189 * Return: void.
18190 */
18191void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18192{
18193 hdd_ap_ctx_t *hdd_ap_ctx;
18194 hdd_hostapd_state_t *hostapd_state;
18195 VOS_STATUS vos_status;
18196 hdd_context_t *hdd_ctx;
18197 tsap_Config_t *pConfig;
18198
18199 if (NULL == ap_adapter) {
18200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18201 FL("ap_adapter is NULL here"));
18202 return;
18203 }
18204
18205 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18206 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18207 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18208 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18209
18210 mutex_lock(&hdd_ctx->sap_lock);
18211 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18212 goto end;
18213
18214 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18215 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18216 goto end;
18217 }
18218
18219 vos_event_reset(&hostapd_state->vosEvent);
18220 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18221 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18222 != VOS_STATUS_SUCCESS) {
18223 goto end;
18224 }
18225
18226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18227 FL("Waiting for SAP to start"));
18228 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18229 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18231 FL("SAP Start failed"));
18232 goto end;
18233 }
18234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18235 FL("SAP Start Success"));
18236 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18237
18238 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18239 hostapd_state->bCommit = TRUE;
18240
18241end:
18242 mutex_unlock(&hdd_ctx->sap_lock);
18243 return;
18244}
18245
Manjeet Singh3ed79242017-01-11 19:04:32 +053018246#ifdef WLAN_FEATURE_TSF
18247
18248/**
18249 * hdd_tsf_cb() - handle tsf request callback
18250 *
18251 * @pcb_cxt: pointer to the hdd_contex
18252 * @ptsf: pointer to struct stsf
18253 *
18254 * Based on the request sent .
18255 *
18256 * Return: Describe the execute result of this routine
18257 */
18258static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18259{
18260 hdd_context_t *hddctx;
18261 int status;
18262 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18263
18264 if (pcb_ctx == NULL || ptsf == NULL) {
18265 hddLog(VOS_TRACE_LEVEL_ERROR,
18266 FL("HDD context is not valid"));
18267 return -EINVAL;
18268 }
18269
18270 hddctx = (hdd_context_t *)pcb_ctx;
18271 status = wlan_hdd_validate_context(hddctx);
18272 if (0 != status)
18273 return -EINVAL;
18274
18275 if (NULL == adapter) {
18276 hddLog(VOS_TRACE_LEVEL_ERROR,
18277 FL("failed to find adapter"));
18278 return -EINVAL;
18279 }
18280
18281 hddLog(VOS_TRACE_LEVEL_INFO,
18282 FL("tsf cb handle event, device_mode is %d"),
18283 adapter->device_mode);
18284
18285 /* copy the return value to hdd_tsf_ctx in adapter*/
18286 if (ptsf->tsf_req_status) {
18287
18288 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18289 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18290 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18291 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18292 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18293
18294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18295 ptsf->tsf_req_status);
18296 return ptsf->tsf_req_status;
18297 }
18298 /* If this is a get request.Store the tsf values in adapter. */
18299 if (!ptsf->set_tsf_req) {
18300 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18301 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18302 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18303 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18304 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18305 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18306
18307 hddLog(VOS_TRACE_LEVEL_INFO,
18308 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18309 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18310 }
18311 else {
18312 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18313 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18314 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18315 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18316 }
18317 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18318 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18319 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18320
18321 /* free allocated mem */
18322 vos_mem_free(ptsf);
18323
18324 return 0;
18325}
18326
18327/**
18328 * hdd_capture_tsf() - capture tsf
18329 *
18330 * @adapter: pointer to adapter
18331 * @buf: pointer to upper layer buf
18332 * @len : the length of buf
18333 *
18334 * This function returns tsf value to uplayer.
18335 *
18336 * Return: Describe the execute result of this routine
18337 */
18338int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18339{
18340 int ret = 0;
18341 hdd_station_ctx_t *hdd_sta_ctx;
18342 hdd_context_t *hdd_ctx;
18343 tSirCapTsfParams cap_tsf_params;
18344 VOS_STATUS status;
18345
18346 if (adapter == NULL || buf == NULL) {
18347 hddLog(VOS_TRACE_LEVEL_ERROR,
18348 FL("invalid pointer"));
18349 return -EINVAL;
18350 }
18351 if (len != 1)
18352 return -EINVAL;
18353
18354 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18355
18356 if (wlan_hdd_validate_context(hdd_ctx)) {
18357 hddLog(VOS_TRACE_LEVEL_ERROR,
18358 FL("invalid hdd ctx"));
18359 return -EINVAL;
18360 }
18361 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18362 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18363 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18364 if (hdd_sta_ctx->conn_info.connState !=
18365 eConnectionState_Associated) {
18366
18367 hddLog(VOS_TRACE_LEVEL_INFO,
18368 FL("failed to cap tsf, not connect with ap"));
18369 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18370 return ret;
18371 }
18372 }
18373 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18374 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18375 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18376 hddLog(VOS_TRACE_LEVEL_INFO,
18377 FL("Soft AP / P2p GO not beaconing"));
18378 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18379 return ret;
18380 }
18381 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18382 hddLog(VOS_TRACE_LEVEL_INFO,
18383 FL("current in capture state, pls reset"));
18384 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18385 } else {
18386 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18387 buf[0] = TSF_RETURN;
18388 cap_tsf_params.session_id = adapter->sessionId;
18389 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18390 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18391
18392 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18393 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18394 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18395 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18396
18397 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18398
18399 if (ret != VOS_STATUS_SUCCESS) {
18400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18401 buf[0] = TSF_CAPTURE_FAIL;
18402 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18403 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18404 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18405 return -EINVAL;
18406 }
18407 /* wait till we get a response from fw */
18408 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18409 tsf_capture_done_event,
18410 HDD_TSF_CAP_REQ_TIMEOUT);
18411
18412 if (!VOS_IS_STATUS_SUCCESS(status)) {
18413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18414 ("capture tsf vos wait for single_event failed!! %d"),
18415 adapter->tsf_cap_ctx.tsf_get_state);
18416
18417 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18418 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18419 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18420
18421 return -EINVAL;
18422 }
18423 }
18424 buf[0] = TSF_RETURN;
18425 hddLog(VOS_TRACE_LEVEL_INFO,
18426 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18427 return ret;
18428}
18429
18430/**
18431 * hdd_indicate_tsf() - return tsf to uplayer
18432 *
18433 * @adapter: pointer to adapter
18434 * @buf: pointer to uplayer buf
18435 * @len : the length of buf
18436 *
18437 * This function returns tsf value to uplayer.
18438 *
18439 * Return: Describe the execute result of this routine
18440 */
18441int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18442{
18443 int ret = 0;
18444 hdd_station_ctx_t *hdd_sta_ctx;
18445 hdd_context_t *hdd_ctx;
18446 tSirCapTsfParams cap_tsf_params;
18447 VOS_STATUS status;
18448
18449 if (adapter == NULL || buf == NULL) {
18450 hddLog(VOS_TRACE_LEVEL_ERROR,
18451 FL("invalid pointer"));
18452 return -EINVAL;
18453 }
18454 if (len != 3)
18455 return -EINVAL;
18456
18457 buf [1] = 0;
18458 buf [2] = 0;
18459 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18460
18461 if (wlan_hdd_validate_context(hdd_ctx)) {
18462 hddLog(VOS_TRACE_LEVEL_ERROR,
18463 FL("invalid hdd ctx"));
18464 return -EINVAL;
18465 }
18466 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18467 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18468 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18469 if (hdd_sta_ctx->conn_info.connState !=
18470 eConnectionState_Associated) {
18471
18472 hddLog(VOS_TRACE_LEVEL_INFO,
18473 FL("failed to cap tsf, not connect with ap"));
18474 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18475 return ret;
18476 }
18477 }
18478 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18479 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18480 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18481 hddLog(VOS_TRACE_LEVEL_INFO,
18482 FL("Soft AP / P2p GO not beaconing"));
18483 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18484 return ret;
18485 }
18486
18487 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18488 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18489 hddLog(VOS_TRACE_LEVEL_INFO,
18490 FL("Not in capture state,Enter capture state first"));
18491 buf[0] = TSF_GET_FAIL;
18492 } else {
18493 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18494 cap_tsf_params.session_id = adapter->sessionId;
18495 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18496 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18497
18498 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18499
18500 if (ret != VOS_STATUS_SUCCESS) {
18501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18502 buf[0] = TSF_CAPTURE_FAIL;
18503 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18504 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18505 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18506 return -EINVAL;
18507 }
18508 /* wait till we get a response from fw */
18509 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18510 tsf_capture_done_event,
18511 HDD_TSF_GET_REQ_TIMEOUT);
18512
18513 if (!VOS_IS_STATUS_SUCCESS(status)) {
18514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18515 ("capture tsf vos wait for single_event failed!! %d"),
18516 status);
18517
18518 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18519 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18520 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18521 return status;
18522 }
18523 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18524 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18525
18526 hddLog(VOS_TRACE_LEVEL_INFO,
18527 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18528 buf[0], buf[1], buf[2]);
18529 }
18530 hddLog(VOS_TRACE_LEVEL_INFO,
18531 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18532 return ret;
18533}
18534
18535void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18536{
18537
18538 if (adapter == NULL) {
18539 hddLog(VOS_TRACE_LEVEL_ERROR,
18540 FL("TSF init on a null adapter!"));
18541 return;
18542 }
18543
18544 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18545 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18546 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18547 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18548 adapter->tsf_cap_ctx.tsf_high = 0;
18549 adapter->tsf_cap_ctx.tsf_low = 0;
18550}
18551
18552#endif
18553
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018554bool hdd_is_memdump_supported(void)
18555{
18556#ifdef WLAN_FEATURE_MEMDUMP
18557 return true;
18558#endif
18559 return false;
18560}
18561
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018562bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18563{
18564 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18565 hdd_adapter_t *adapter;
18566 VOS_STATUS status;
18567
18568 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18569 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18570 adapter = adapter_node->pAdapter;
18571 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18572 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18573 test_bit(DEVICE_IFACE_OPENED,
18574 &adapter->event_flags)){
18575 return true;
18576 }
18577 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18578 adapter_node = next;
18579 }
18580
18581 return false;
18582}
18583
Jeff Johnson295189b2012-06-20 16:38:30 -070018584//Register the module init/exit functions
18585module_init(hdd_module_init);
18586module_exit(hdd_module_exit);
18587
18588MODULE_LICENSE("Dual BSD/GPL");
18589MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18590MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18591
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018592static const struct kernel_param_ops con_mode_ops = {
18593 .set = con_mode_handler,
18594 .get = param_get_int,
18595};
18596
18597static const struct kernel_param_ops fwpath_ops = {
18598 .set = fwpath_changed_handler,
18599 .get = param_get_string,
18600};
18601
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018602#ifdef MODULE
18603module_param(con_mode, int, 0);
18604#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018605module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018606 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018607#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018608
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018609module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018610 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018611
18612module_param(enable_dfs_chan_scan, int,
18613 S_IRUSR | S_IRGRP | S_IROTH);
18614
18615module_param(enable_11d, int,
18616 S_IRUSR | S_IRGRP | S_IROTH);
18617
18618module_param(country_code, charp,
18619 S_IRUSR | S_IRGRP | S_IROTH);