blob: e3686e8e87b358a63304541cf1c6272d889b3950 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Arunk Khandavalli95608be2019-01-22 13:12:54 +05302 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053065#include <vos_nvitem.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <linux/etherdevice.h>
68#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#ifdef ANI_BUS_TYPE_PLATFORM
70#include <linux/wcnss_wlan.h>
71#endif //ANI_BUS_TYPE_PLATFORM
72#ifdef ANI_BUS_TYPE_PCI
73#include "wcnss_wlan.h"
74#endif /* ANI_BUS_TYPE_PCI */
75#include <wlan_hdd_tx_rx.h>
76#include <palTimer.h>
77#include <wniApi.h>
78#include <wlan_nlink_srv.h>
79#include <wlan_btc_svc.h>
80#include <wlan_hdd_cfg.h>
81#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053082#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#include <wlan_hdd_wowl.h>
84#include <wlan_hdd_misc.h>
85#include <wlan_hdd_wext.h>
86#ifdef WLAN_BTAMP_FEATURE
87#include <bap_hdd_main.h>
88#include <bapInternal.h>
89#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053090#include "wlan_hdd_trace.h"
91#include "vos_types.h"
92#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070093#include <linux/wireless.h>
94#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053095#include <linux/inetdevice.h>
96#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070097#include "wlan_hdd_cfg80211.h"
98#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include "sapApi.h"
102#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700103#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
105#include <soc/qcom/subsystem_restart.h>
106#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <wlan_hdd_hostapd.h>
110#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include "wlan_hdd_dev_pwr.h"
113#ifdef WLAN_BTAMP_FEATURE
114#include "bap_hdd_misc.h"
115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700117#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800118#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530119#ifdef FEATURE_WLAN_TDLS
120#include "wlan_hdd_tdls.h"
121#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700122#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530123#include "sapInternal.h"
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +0530124#include "wlan_hdd_request_manager.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
155
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700156#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700157static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700159
Jeff Johnsone7245742012-09-05 17:12:55 -0700160/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800161 * spinlock for synchronizing asynchronous request/response
162 * (full description of use in wlan_hdd_main.h)
163 */
164DEFINE_SPINLOCK(hdd_context_lock);
165
166/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 * The rate at which the driver sends RESTART event to supplicant
168 * once the function 'vos_wlanRestart()' is called
169 *
170 */
171#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
172#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700173
174/*
175 * Size of Driver command strings from upper layer
176 */
177#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
178#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
179
Abhishek Singh00b71972016-01-07 10:51:04 +0530180#ifdef WLAN_FEATURE_RMC
181/*
182 * Ibss prop IE from command will be of size:
183 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
184 * OUI_DATA should be at least 3 bytes long
185 */
186#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
187#endif
188
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800189#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190#define TID_MIN_VALUE 0
191#define TID_MAX_VALUE 15
192static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
193 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800194static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
195 tCsrEseBeaconReq *pEseBcnReq);
196#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700197
Atul Mittal1d722422014-03-19 11:15:07 +0530198/*
199 * Maximum buffer size used for returning the data back to user space
200 */
201#define WLAN_MAX_BUF_SIZE 1024
202#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700203
Abhishek Singh00b71972016-01-07 10:51:04 +0530204/*
205 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
206 * we will split the printing.
207 */
208#define NUM_OF_STA_DATA_TO_PRINT 16
209
210#ifdef WLAN_FEATURE_RMC
211#define WLAN_NLINK_CESIUM 30
212#endif
213
c_hpothu92367912014-05-01 15:18:17 +0530214//wait time for beacon miss rate.
215#define BCN_MISS_RATE_TIME 500
216
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530217/*
218 * Android DRIVER command structures
219 */
220struct android_wifi_reassoc_params {
221 unsigned char bssid[18];
222 int channel;
223};
224
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530225static vos_wake_lock_t wlan_wake_lock;
226
Jeff Johnson295189b2012-06-20 16:38:30 -0700227/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700228static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700231static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
233static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530234
235#ifdef WLAN_FEATURE_RMC
236static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
237
238static int hdd_open_cesium_nl_sock(void);
239static void hdd_close_cesium_nl_sock(void);
240static struct sock *cesium_nl_srv_sock;
241static v_U16_t cesium_pid;
242
243static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
244 tANI_U8 *tx_fail_count,
245 tANI_U16 *pid);
246
247static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
248
249#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700250void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800251void hdd_set_wlan_suspend_mode(bool suspend);
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530252void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
Jeff Johnsone7245742012-09-05 17:12:55 -0700253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530255 struct sk_buff *skb
256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
257 , void *accel_priv
258#endif
259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
260 , select_queue_fallback_t fallback
261#endif
262);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263
264#ifdef WLAN_FEATURE_PACKET_FILTERING
265static void hdd_set_multicast_list(struct net_device *dev);
266#endif
267
268void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800270#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800271void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
272static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700273static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
274 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
275 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530276static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
277 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800278#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530279
280/* Store WLAN driver info in a global variable such that crash debugger
281 can extract it from driver debug symbol and crashdump for post processing */
282tANI_U8 g_wlan_driver[ ] = "pronto_driver";
283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800286#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700287
Mihir Shetee1093ba2014-01-21 20:13:32 +0530288static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530289const char * hdd_device_modetoString(v_U8_t device_mode)
290{
291 switch(device_mode)
292 {
293 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
294 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
296 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
297 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
298 CASE_RETURN_STRING( WLAN_HDD_FTM );
299 CASE_RETURN_STRING( WLAN_HDD_IBSS );
300 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
301 default:
302 return "device_mode Unknown";
303 }
304}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530305
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530306static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 unsigned long state,
308 void *ndev)
309{
310 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700312 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#ifdef WLAN_BTAMP_FEATURE
314 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700317
318 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700319 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700320 (strncmp(dev->name, "p2p", 3)))
321 return NOTIFY_DONE;
322
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700325
Jeff Johnson27cee452013-03-27 11:10:24 -0700326 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 VOS_ASSERT(0);
330 return NOTIFY_DONE;
331 }
332
Jeff Johnson27cee452013-03-27 11:10:24 -0700333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
334 if (NULL == pHddCtx)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
337 VOS_ASSERT(0);
338 return NOTIFY_DONE;
339 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800340 if (pHddCtx->isLogpInProgress)
341 return NOTIFY_DONE;
342
Jeff Johnson27cee452013-03-27 11:10:24 -0700343
344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
345 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700346
347 switch (state) {
348 case NETDEV_REGISTER:
349 break;
350
351 case NETDEV_UNREGISTER:
352 break;
353
354 case NETDEV_UP:
355 break;
356
357 case NETDEV_DOWN:
358 break;
359
360 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700361 if(TRUE == pAdapter->isLinkUpSvcNeeded)
362 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 break;
364
365 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530367 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530368 {
369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
370 "%s: Timeout occurred while waiting for abortscan %ld",
371 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373 else
374 {
375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530376 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 status = WLANBAP_StopAmp();
381 if(VOS_STATUS_SUCCESS != status )
382 {
383 pHddCtx->isAmpAllowed = VOS_TRUE;
384 hddLog(VOS_TRACE_LEVEL_FATAL,
385 "%s: Failed to stop AMP", __func__);
386 }
387 else
388 {
389 //a state m/c implementation in PAL is TBD to avoid this delay
390 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700391 if ( pHddCtx->isAmpAllowed )
392 {
393 WLANBAP_DeregisterFromHCI();
394 pHddCtx->isAmpAllowed = VOS_FALSE;
395 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 }
397#endif //WLAN_BTAMP_FEATURE
398 break;
399
400 default:
401 break;
402 }
403
404 return NOTIFY_DONE;
405}
406
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530407static int hdd_netdev_notifier_call(struct notifier_block * nb,
408 unsigned long state,
409 void *ndev)
410{
411 int ret;
412 vos_ssr_protect(__func__);
413 ret = __hdd_netdev_notifier_call( nb, state, ndev);
414 vos_ssr_unprotect(__func__);
415 return ret;
416}
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418struct notifier_block hdd_netdev_notifier = {
419 .notifier_call = hdd_netdev_notifier_call,
420};
421
422/*---------------------------------------------------------------------------
423 * Function definitions
424 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700425void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
426void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700427//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700429#ifndef MODULE
430/* current con_mode - used only for statically linked driver
431 * con_mode is changed by userspace to indicate a mode change which will
432 * result in calling the module exit and init functions. The module
433 * exit function will clean up based on the value of con_mode prior to it
434 * being changed by userspace. So curr_con_mode records the current con_mode
435 * for exit when con_mode becomes the next mode for init
436 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700437static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700438#endif
439
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530440#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
441/**
442 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
443 * @hdd_ctx: hdd global context
444 *
445 * Return: none
446 */
447static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
448{
449 uint8_t i;
450
451 mutex_init(&hdd_ctx->op_ctx.op_lock);
452 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
453 {
454 hdd_ctx->op_ctx.op_table[i].request_id = 0;
455 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
456 }
457}
458#else
459static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
460{
461}
462#endif
463
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800464/**---------------------------------------------------------------------------
465
466 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
467
468 Called immediately after the cfg.ini is read in order to configure
469 the desired trace levels.
470
471 \param - moduleId - module whose trace level is being configured
472 \param - bitmask - bitmask of log levels to be enabled
473
474 \return - void
475
476 --------------------------------------------------------------------------*/
477static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
478{
479 wpt_tracelevel level;
480
481 /* if the bitmask is the default value, then a bitmask was not
482 specified in cfg.ini, so leave the logging level alone (it
483 will remain at the "compiled in" default value) */
484 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
485 {
486 return;
487 }
488
489 /* a mask was specified. start by disabling all logging */
490 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
491
492 /* now cycle through the bitmask until all "set" bits are serviced */
493 level = VOS_TRACE_LEVEL_FATAL;
494 while (0 != bitmask)
495 {
496 if (bitmask & 1)
497 {
498 vos_trace_setValue(moduleId, level, 1);
499 }
500 level++;
501 bitmask >>= 1;
502 }
503}
504
505
Jeff Johnson295189b2012-06-20 16:38:30 -0700506/**---------------------------------------------------------------------------
507
508 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
509
510 Called immediately after the cfg.ini is read in order to configure
511 the desired trace levels in the WDI.
512
513 \param - moduleId - module whose trace level is being configured
514 \param - bitmask - bitmask of log levels to be enabled
515
516 \return - void
517
518 --------------------------------------------------------------------------*/
519static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
520{
521 wpt_tracelevel level;
522
523 /* if the bitmask is the default value, then a bitmask was not
524 specified in cfg.ini, so leave the logging level alone (it
525 will remain at the "compiled in" default value) */
526 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
527 {
528 return;
529 }
530
531 /* a mask was specified. start by disabling all logging */
532 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
533
534 /* now cycle through the bitmask until all "set" bits are serviced */
535 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
536 while (0 != bitmask)
537 {
538 if (bitmask & 1)
539 {
540 wpalTraceSetLevel(moduleId, level, 1);
541 }
542 level++;
543 bitmask >>= 1;
544 }
545}
Jeff Johnson295189b2012-06-20 16:38:30 -0700546
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530547/*
548 * FUNCTION: wlan_hdd_validate_context
549 * This function is used to check the HDD context
550 */
551int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
552{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530553
554 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
555 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530557 "%s: HDD context is Null", __func__);
558 return -ENODEV;
559 }
560
561 if (pHddCtx->isLogpInProgress)
562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530564 "%s: LOGP %s. Ignore!!", __func__,
565 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
566 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530567 return -EAGAIN;
568 }
569
Mihir Shete18156292014-03-11 15:38:30 +0530570 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530573 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
574 return -EAGAIN;
575 }
576 return 0;
577}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578#ifdef CONFIG_ENABLE_LINUX_REG
579void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
580{
581 hdd_adapter_t *pAdapter = NULL;
582 hdd_station_ctx_t *pHddStaCtx = NULL;
583 eCsrPhyMode phyMode;
584 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530585
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700586 if (NULL == pHddCtx)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "HDD Context is null !!");
590 return ;
591 }
592
593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
594 if (NULL == pAdapter)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "pAdapter is null !!");
598 return ;
599 }
600
601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
602 if (NULL == pHddStaCtx)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "pHddStaCtx is null !!");
606 return ;
607 }
608
609 cfg_param = pHddCtx->cfg_ini;
610 if (NULL == cfg_param)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
613 "cfg_params not available !!");
614 return ;
615 }
616
617 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
618
619 if (!pHddCtx->isVHT80Allowed)
620 {
621 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
622 (eCSR_DOT11_MODE_11ac == phyMode) ||
623 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
626 "Setting phymode to 11n!!");
627 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
628 }
629 }
630 else
631 {
632 /*New country Supports 11ac as well resetting value back from .ini*/
633 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
634 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
635 return ;
636 }
637
638 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
639 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
640 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
641 {
642 VOS_STATUS vosStatus;
643
644 // need to issue a disconnect to CSR.
645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
646 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
647 pAdapter->sessionId,
648 eCSR_DISCONNECT_REASON_UNSPECIFIED );
649
650 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530651 {
652 long ret;
653
654 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 if (0 >= ret)
657 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
658 ret);
659 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660
661 }
662}
663#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530664void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
665{
666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
668 hdd_config_t *cfg_param;
669 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530670 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530671
672 if (NULL == pHddCtx)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "HDD Context is null !!");
676 return ;
677 }
678
679 cfg_param = pHddCtx->cfg_ini;
680
681 if (NULL == cfg_param)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
684 "cfg_params not available !!");
685 return ;
686 }
687
688 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
689
690 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
691 {
692 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
693 (eCSR_DOT11_MODE_11ac == phyMode) ||
694 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
695 {
696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 "Setting phymode to 11n!!");
698 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
699 }
700 }
701 else
702 {
703 /*New country Supports 11ac as well resetting value back from .ini*/
704 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
705 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
706 return ;
707 }
708
709 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
710 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
711 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
712 {
713 VOS_STATUS vosStatus;
714
715 // need to issue a disconnect to CSR.
716 INIT_COMPLETION(pAdapter->disconnect_comp_var);
717 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
718 pAdapter->sessionId,
719 eCSR_DISCONNECT_REASON_UNSPECIFIED );
720
721 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530722 {
723 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530725 if (ret <= 0)
726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "wait on disconnect_comp_var is failed %ld", ret);
729 }
730 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530731
732 }
733}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700734#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530735
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700736void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
737{
738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
739 hdd_config_t *cfg_param;
740
741 if (NULL == pHddCtx)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "HDD Context is null !!");
745 return ;
746 }
747
748 cfg_param = pHddCtx->cfg_ini;
749
750 if (NULL == cfg_param)
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
753 "cfg_params not available !!");
754 return ;
755 }
756
Agarwal Ashish738843c2014-09-25 12:27:56 +0530757 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
758 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700759 {
760 /*New country doesn't support DFS */
761 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
762 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530763 else
764 {
765 /* New country Supports DFS as well resetting value back from .ini */
766 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
767 cfg_param->enableDFSChnlScan);
768 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700769
770}
771
Abhishek Singh00b71972016-01-07 10:51:04 +0530772#ifdef WLAN_FEATURE_RMC
773static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
774{
775 tANI_U8 *inPtr = pValue;
776 int tempInt;
777 int v = 0;
778 char buf[32];
779 *pRmcEnable = 0;
780
781 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
782 /*no argument after the command*/
783 if (NULL == inPtr)
784 {
785 return 0;
786 }
787
788 /*no space after the command*/
789 else if (SPACE_ASCII_VALUE != *inPtr)
790 {
791 return 0;
792 }
793
794 /*removing empty spaces*/
795 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
796
797 /*no argument followed by spaces*/
798 if ('\0' == *inPtr)
799 {
800 return 0;
801 }
802
803 /* getting the first argument which enables or disables RMC
804 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530805 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530806 v = kstrtos32(buf, 10, &tempInt);
807 if ( v < 0)
808 {
809 return -EINVAL;
810 }
811
812 *pRmcEnable = tempInt;
813
814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
815 "ucRmcEnable: %d", *pRmcEnable);
816
817 return 0;
818}
819
820/* Function header left blank Intentionally */
821static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
822 tANI_U32 *pActionPeriod)
823{
824 tANI_U8 *inPtr = pValue;
825 int tempInt;
826 int v = 0;
827 char buf[32];
828 *pActionPeriod = 0;
829
830 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
831 /*no argument after the command*/
832 if (NULL == inPtr)
833 {
834 return -EINVAL;
835 }
836
837 /*no space after the command*/
838 else if (SPACE_ASCII_VALUE != *inPtr)
839 {
840 return -EINVAL;
841 }
842
843 /*removing empty spaces*/
844 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
845
846 /*no argument followed by spaces*/
847 if ('\0' == *inPtr)
848 {
849 return 0;
850 }
851
852 /* getting the first argument which enables or disables RMC
853 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530854 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530855 v = kstrtos32(buf, 10, &tempInt);
856 if ( v < 0)
857 {
858 return -EINVAL;
859 }
860
861 /* Range checking for passed paramter */
862 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
863 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
864 {
865 return -EINVAL;
866 }
867
868 *pActionPeriod = tempInt;
869
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
871 "uActionPeriod: %d", *pActionPeriod);
872
873 return 0;
874}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530875
876/**
877 * hdd_set_vowifi_mode() - Process VOWIFI command.
878 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530879 * @enable: Value to be sent as a part of the VOWIFI command
880 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530881 * Invoke the SME api if station is connected in 2.4 GHz band.
882 * Also start split scan if VOWIFIMODE and dynamic split scan
883 * both are enabled.
884
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530885 * Return: void
886 */
887void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
888{
889 tANI_U8 sta_chan;
890
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530891 if (!hdd_ctx->cfg_ini) {
892 hddLog(LOGE, "cfg_ini got NULL");
893 return;
894 }
895
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530896 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
897
Dundi Ravitejae110a042018-04-18 13:11:37 +0530898 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530899 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530900 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
902 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530903
904 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
905 hdd_ctx->is_vowifi_enabled = true;
906 hdd_ctx->issplitscan_enabled = TRUE;
907 sme_enable_disable_split_scan(hdd_ctx->hHal,
908 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
909 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
910 } else {
911 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530912 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530913}
Abhishek Singh00b71972016-01-07 10:51:04 +0530914
915/* Function header left blank Intentionally */
916static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
917 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
918{
919 tANI_U8 *inPtr = pValue;
920 int tempInt;
921 int v = 0;
922 char buf[32];
923 *pRate = 0;
924 *pTxFlags = 0;
925
926 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
927 /*no argument after the command*/
928 if (NULL == inPtr)
929 {
930 return -EINVAL;
931 }
932
933 /*no space after the command*/
934 else if (SPACE_ASCII_VALUE != *inPtr)
935 {
936 return -EINVAL;
937 }
938
939 /*removing empty spaces*/
940 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
941
942 /*no argument followed by spaces*/
943 if ('\0' == *inPtr)
944 {
945 return 0;
946 }
947
948 /*
949 * getting the first argument which sets multicast rate.
950 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530951 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530952 v = kstrtos32(buf, 10, &tempInt);
953 if ( v < 0)
954 {
955 return -EINVAL;
956 }
957
958 /*
959 * Validate the multicast rate.
960 */
961 switch (tempInt)
962 {
963 default:
964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
965 "Unsupported rate: %d", tempInt);
966 return -EINVAL;
967 case 0:
968 case 6:
969 case 9:
970 case 12:
971 case 18:
972 case 24:
973 case 36:
974 case 48:
975 case 54:
976 *pTxFlags = eHAL_TX_RATE_LEGACY;
977 *pRate = tempInt * 10;
978 break;
979 case 65:
980 *pTxFlags = eHAL_TX_RATE_HT20;
981 *pRate = tempInt * 10;
982 break;
983 case 72:
984 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
985 *pRate = 722; /* fractional rate 72.2 Mbps */
986 break;
987 }
988
989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
990 "Rate: %d", *pRate);
991
992 return 0;
993}
994
995/**---------------------------------------------------------------------------
996
997 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
998 Peer Info request
999
1000 This is an asynchronous callback function from SME when the peer info
1001 is received
1002
1003 \pUserData -> Adapter private data
1004 \pPeerInfoRsp -> Peer info response
1005
1006 \return - 0 for success non-zero for failure
1007 --------------------------------------------------------------------------*/
1008static void
1009hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1010{
1011 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1012 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1013 hdd_station_ctx_t *pStaCtx;
1014 v_U8_t i;
1015
1016 /*Sanity check*/
1017 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1018 {
1019 hddLog(LOGE,
1020 FL("invalid adapter or adapter has invalid magic"));
1021 return;
1022 }
1023
1024 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1025 if (NULL != pStaCtx && NULL != pPeerInfo &&
1026 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1027 {
1028 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1029 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1030
1031 /* Paranoia check */
1032 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1033 {
1034 for (i = 0; i < pPeerInfo->numPeers; i++)
1035 {
1036 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1037 &pPeerInfo->peerInfoParams[i],
1038 sizeof(hdd_ibss_peer_info_params_t));
1039 }
1040 hddLog(LOG1,
1041 FL("Peer Info copied in HDD"));
1042 }
1043 else
1044 {
1045 hddLog(LOGE,
1046 FL(" Number of peers %d returned is more than limit %d"),
1047 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1048 }
1049 }
1050 else
1051 {
1052 hddLog(LOG1,
1053 FL("peerInfo returned is NULL"));
1054 }
1055
1056 complete(&pAdapter->ibss_peer_info_comp);
1057}
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1062
1063 Request function to get IBSS peer info from lower layers
1064
1065 \pAdapter -> Adapter context
1066
1067 \return - 0 for success non-zero for failure
1068 --------------------------------------------------------------------------*/
1069static
1070VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1071{
1072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1073 long status;
1074 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1075
1076 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1077
1078 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1079 hdd_cfg80211_get_ibss_peer_info_cb,
1080 VOS_TRUE, 0xFF);
1081
1082 if (VOS_STATUS_SUCCESS == retStatus)
1083 {
1084 status = wait_for_completion_interruptible_timeout
1085 (&pAdapter->ibss_peer_info_comp,
1086 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1087
1088 /* status will be 0 if timed out */
1089 if (status <= 0)
1090 {
1091 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1092 __func__, status);
1093 retStatus = VOS_STATUS_E_FAILURE;
1094 return retStatus;
1095 }
1096 }
1097 else
1098 {
1099 hddLog(VOS_TRACE_LEVEL_WARN,
1100 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1101 }
1102
1103 return retStatus;
1104}
1105
1106/**---------------------------------------------------------------------------
1107
1108 \brief hdd_cfg80211_get_ibss_peer_info() -
1109
1110 Request function to get IBSS peer info from lower layers
1111
1112 \pAdapter -> Adapter context
1113 \staIdx -> Sta index for which the peer info is requested
1114
1115 \return - 0 for success non-zero for failure
1116 --------------------------------------------------------------------------*/
1117static VOS_STATUS
1118hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1119{
1120 long status;
1121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1122 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1123
1124 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1125
1126 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1127 hdd_cfg80211_get_ibss_peer_info_cb,
1128 VOS_FALSE, staIdx);
1129
1130 if (VOS_STATUS_SUCCESS == retStatus)
1131 {
1132 status = wait_for_completion_interruptible_timeout
1133 (&pAdapter->ibss_peer_info_comp,
1134 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1135
1136 /* status = 0 on timeout */
1137 if (status <= 0)
1138 {
1139 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1140 __func__, status);
1141 retStatus = VOS_STATUS_E_FAILURE;
1142 return retStatus;
1143 }
1144 }
1145 else
1146 {
1147 hddLog(VOS_TRACE_LEVEL_WARN,
1148 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1149 }
1150
1151 return retStatus;
1152}
1153
1154/* Function header left blank Intentionally */
1155VOS_STATUS
1156hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1157{
1158 tANI_U8 *inPtr = pValue;
1159 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1160
1161 /*no argument after the command*/
1162 if (NULL == inPtr)
1163 {
1164 return VOS_STATUS_E_FAILURE;;
1165 }
1166
1167 /*no space after the command*/
1168 else if (SPACE_ASCII_VALUE != *inPtr)
1169 {
1170 return VOS_STATUS_E_FAILURE;;
1171 }
1172
1173 /*removing empty spaces*/
1174 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1175
1176 /*no argument followed by spaces*/
1177 if ('\0' == *inPtr)
1178 {
1179 return VOS_STATUS_E_FAILURE;;
1180 }
1181
1182 /*getting the first argument ie the peer mac address */
1183 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1184 inPtr[11] != ':' || inPtr[14] != ':')
1185 {
1186 return VOS_STATUS_E_FAILURE;;
1187 }
1188 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1189 (unsigned int *)&pPeerMacAddr->bytes[0],
1190 (unsigned int *)&pPeerMacAddr->bytes[1],
1191 (unsigned int *)&pPeerMacAddr->bytes[2],
1192 (unsigned int *)&pPeerMacAddr->bytes[3],
1193 (unsigned int *)&pPeerMacAddr->bytes[4],
1194 (unsigned int *)&pPeerMacAddr->bytes[5]);
1195
1196 /* The command buffer seems to be fine */
1197 return VOS_STATUS_SUCCESS;
1198}
1199
1200/* Function header left blank Intentionally */
1201static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1202 tANI_U32 limit)
1203{
1204 tANI_U8 len;
1205 tANI_U8 data;
1206
1207 /* skip white space */
1208 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1209 {
1210 command++;
1211 limit--;
1212 }
1213
1214 /* skip element id and element length */
1215 len = 2;
1216
1217 /* extract oui */
1218 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1219 (limit > 1))
1220 {
1221 /* Convert ASCII to decimal */
1222 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1223 ie[len++] = data;
1224 command += 2;
1225 limit -= 2;
1226 }
1227
1228 /* skip white space */
1229 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1230 {
1231 command++;
1232 limit--;
1233 }
1234
1235 /* extract data */
1236 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1237 (limit > 1))
1238 {
1239 /* Convert ASCII to decimal */
1240 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1241 ie[len++] = data;
1242 command += 2;
1243 limit -= 2;
1244 }
1245
1246 /* fill element id and element length */
1247 ie[0] = IE_EID_VENDOR;
1248 ie[1] = len - 2;
1249
1250 return len;
1251}
1252
1253static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1254{
1255 tANI_U32 ieLenPresent = 0;
1256 int left = addIeLen;
1257 v_U8_t *ptr = addIePtr;
1258 v_U8_t elem_id,elem_len;
1259
1260 while(left >= 2)
1261 {
1262 elem_id = ptr[0];
1263 elem_len = ptr[1];
1264 left -= 2;
1265 if(elem_len > left)
1266 {
1267 hddLog(LOGE,
1268 FL("****Invalid elem_len=%d left=%d*****"),
1269 elem_len,left);
1270 return 0;
1271 }
1272 if ((elem_id == IE_EID_VENDOR) &&
1273 (left >= WPA_OUI_TYPE_SIZE))
1274 {
1275 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1276 WPA_OUI_TYPE_SIZE))
1277 {
1278 ieLenPresent += elem_len + 2;
1279 return ieLenPresent;
1280 }
1281 }
1282 ieLenPresent += (elem_len + 2);
1283 left -= elem_len;
1284 ptr += (elem_len + 2);
1285 }
1286 return 0;
1287}
1288
1289#endif /* WLAN_FEATURE_RMC */
1290
Rajeev79dbe4c2013-10-05 11:03:42 +05301291#ifdef FEATURE_WLAN_BATCH_SCAN
1292
1293/**---------------------------------------------------------------------------
1294
1295 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1296 input string
1297
1298 This function extracts assigned integer from string in below format:
1299 "STRING=10" : extracts integer 10 from this string
1300
1301 \param - pInPtr Pointer to input string
1302 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1303 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1304 assigned
1305 \param - pLastArg to tell whether it is last arguement in input string or
1306 not
1307
1308 \return - NULL for failure cases
1309 pointer to next arguement in input string for success cases
1310 --------------------------------------------------------------------------*/
1311static tANI_U8 *
1312hdd_extract_assigned_int_from_str
1313(
1314 tANI_U8 *pInPtr,
1315 tANI_U8 base,
1316 tANI_U32 *pOutPtr,
1317 tANI_U8 *pLastArg
1318)
1319{
1320 int tempInt;
1321 int v = 0;
1322 char buf[32];
1323 int val = 0;
1324 *pLastArg = FALSE;
1325
1326 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1327 if (NULL == pInPtr)
1328 {
1329 return NULL;
1330 }
1331
1332 pInPtr++;
1333
1334 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1335
1336 val = sscanf(pInPtr, "%32s ", buf);
1337 if (val < 0 && val > strlen(pInPtr))
1338 {
1339 return NULL;
1340 }
1341 pInPtr += val;
1342 v = kstrtos32(buf, base, &tempInt);
1343 if (v < 0)
1344 {
1345 return NULL;
1346 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001347 if (tempInt < 0)
1348 {
1349 tempInt = 0;
1350 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301351 *pOutPtr = tempInt;
1352
1353 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1354 if (NULL == pInPtr)
1355 {
1356 *pLastArg = TRUE;
1357 return NULL;
1358 }
1359 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1360
1361 return pInPtr;
1362}
1363
1364/**---------------------------------------------------------------------------
1365
1366 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1367 input string
1368
1369 This function extracts assigned character from string in below format:
1370 "STRING=A" : extracts char 'A' from this string
1371
1372 \param - pInPtr Pointer to input string
1373 \param - pOutPtr Pointer to variable in which extracted char needs to be
1374 assigned
1375 \param - pLastArg to tell whether it is last arguement in input string or
1376 not
1377
1378 \return - NULL for failure cases
1379 pointer to next arguement in input string for success cases
1380 --------------------------------------------------------------------------*/
1381static tANI_U8 *
1382hdd_extract_assigned_char_from_str
1383(
1384 tANI_U8 *pInPtr,
1385 tANI_U8 *pOutPtr,
1386 tANI_U8 *pLastArg
1387)
1388{
1389 *pLastArg = FALSE;
1390
1391 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1392 if (NULL == pInPtr)
1393 {
1394 return NULL;
1395 }
1396
1397 pInPtr++;
1398
1399 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1400
1401 *pOutPtr = *pInPtr;
1402
1403 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1404 if (NULL == pInPtr)
1405 {
1406 *pLastArg = TRUE;
1407 return NULL;
1408 }
1409 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1410
1411 return pInPtr;
1412}
1413
1414
1415/**---------------------------------------------------------------------------
1416
1417 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1418
1419 This function parses set batch scan command in below format:
1420 WLS_BATCHING_SET <space> followed by below arguements
1421 "SCANFREQ=XX" : Optional defaults to 30 sec
1422 "MSCAN=XX" : Required number of scans to attempt to batch
1423 "BESTN=XX" : Best Network (RSSI) defaults to 16
1424 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1425 A. implies only 5 GHz , B. implies only 2.4GHz
1426 "RTT=X" : optional defaults to 0
1427 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1428 error
1429
1430 For example input commands:
1431 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1432 translated into set batch scan with following parameters:
1433 a) Frequence 60 seconds
1434 b) Batch 10 scans together
1435 c) Best RSSI to be 20
1436 d) 5GHz band only
1437 e) RTT is equal to 0
1438
1439 \param - pValue Pointer to input channel list
1440 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1441
1442 \return - 0 for success non-zero for failure
1443
1444 --------------------------------------------------------------------------*/
1445static int
1446hdd_parse_set_batchscan_command
1447(
1448 tANI_U8 *pValue,
1449 tSirSetBatchScanReq *pHddSetBatchScanReq
1450)
1451{
1452 tANI_U8 *inPtr = pValue;
1453 tANI_U8 val = 0;
1454 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301455 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001456 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301457 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1458 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1459 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001460 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301461
Rajeev79dbe4c2013-10-05 11:03:42 +05301462 /*go to space after WLS_BATCHING_SET command*/
1463 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1464 /*no argument after the command*/
1465 if (NULL == inPtr)
1466 {
1467 return -EINVAL;
1468 }
1469
1470 /*no space after the command*/
1471 else if (SPACE_ASCII_VALUE != *inPtr)
1472 {
1473 return -EINVAL;
1474 }
1475
1476 /*removing empty spaces*/
1477 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1478
1479 /*no argument followed by spaces*/
1480 if ('\0' == *inPtr)
1481 {
1482 return -EINVAL;
1483 }
1484
1485 /*check and parse SCANFREQ*/
1486 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1487 {
1488 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001489 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001490
Rajeev Kumarc933d982013-11-18 20:04:20 -08001491 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001492 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001493 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001494 }
1495
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 if ( (NULL == inPtr) || (TRUE == lastArg))
1497 {
1498 return -EINVAL;
1499 }
1500 }
1501
1502 /*check and parse MSCAN*/
1503 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1504 {
1505 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001506 &nMscan, &lastArg);
1507
1508 if (0 == nMscan)
1509 {
1510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1511 "invalid MSCAN=%d", nMscan);
1512 return -EINVAL;
1513 }
1514
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 if (TRUE == lastArg)
1516 {
1517 goto done;
1518 }
1519 else if (NULL == inPtr)
1520 {
1521 return -EINVAL;
1522 }
1523 }
1524 else
1525 {
1526 return -EINVAL;
1527 }
1528
1529 /*check and parse BESTN*/
1530 if ((strncmp(inPtr, "BESTN", 5) == 0))
1531 {
1532 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001533 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001534
Rajeev Kumarc933d982013-11-18 20:04:20 -08001535 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001536 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001537 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001538 }
1539
Rajeev79dbe4c2013-10-05 11:03:42 +05301540 if (TRUE == lastArg)
1541 {
1542 goto done;
1543 }
1544 else if (NULL == inPtr)
1545 {
1546 return -EINVAL;
1547 }
1548 }
1549
1550 /*check and parse CHANNEL*/
1551 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1552 {
1553 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001554
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 if (('A' == val) || ('a' == val))
1556 {
c_hpothuebf89732014-02-25 13:00:24 +05301557 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301558 }
1559 else if (('B' == val) || ('b' == val))
1560 {
c_hpothuebf89732014-02-25 13:00:24 +05301561 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301562 }
1563 else
1564 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001565 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1566 }
1567
1568 if (TRUE == lastArg)
1569 {
1570 goto done;
1571 }
1572 else if (NULL == inPtr)
1573 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 return -EINVAL;
1575 }
1576 }
1577
1578 /*check and parse RTT*/
1579 if ((strncmp(inPtr, "RTT", 3) == 0))
1580 {
1581 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001582 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301583 if (TRUE == lastArg)
1584 {
1585 goto done;
1586 }
1587 if (NULL == inPtr)
1588 {
1589 return -EINVAL;
1590 }
1591 }
1592
1593
1594done:
1595
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001596 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1597 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1598 pHddSetBatchScanReq->bestNetwork = nBestN;
1599 pHddSetBatchScanReq->rfBand = ucRfBand;
1600 pHddSetBatchScanReq->rtt = nRtt;
1601
Rajeev79dbe4c2013-10-05 11:03:42 +05301602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1603 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1604 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1605 pHddSetBatchScanReq->scanFrequency,
1606 pHddSetBatchScanReq->numberOfScansToBatch,
1607 pHddSetBatchScanReq->bestNetwork,
1608 pHddSetBatchScanReq->rfBand,
1609 pHddSetBatchScanReq->rtt);
1610
1611 return 0;
1612}/*End of hdd_parse_set_batchscan_command*/
1613
1614/**---------------------------------------------------------------------------
1615
1616 \brief hdd_set_batch_scan_req_callback () - This function is called after
1617 receiving set batch scan response from FW and it saves set batch scan
1618 response data FW to HDD context and sets the completion event on
1619 which hdd_ioctl is waiting
1620
1621 \param - callbackContext Pointer to HDD adapter
1622 \param - pRsp Pointer to set batch scan response data received from FW
1623
1624 \return - nothing
1625
1626 --------------------------------------------------------------------------*/
1627static void hdd_set_batch_scan_req_callback
1628(
1629 void *callbackContext,
1630 tSirSetBatchScanRsp *pRsp
1631)
1632{
1633 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1634 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1635
1636 /*sanity check*/
1637 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: Invalid pAdapter magic", __func__);
1641 VOS_ASSERT(0);
1642 return;
1643 }
1644 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1645
1646 /*save set batch scan response*/
1647 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1648
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1650 "Received set batch scan rsp from FW with nScansToBatch=%d",
1651 pHddSetBatchScanRsp->nScansToBatch);
1652
1653 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1654 complete(&pAdapter->hdd_set_batch_scan_req_var);
1655
1656 return;
1657}/*End of hdd_set_batch_scan_req_callback*/
1658
1659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1663 info in hdd batch scan response queue
1664
1665 \param - pAdapter Pointer to hdd adapter
1666 \param - pAPMetaInfo Pointer to access point meta info
1667 \param - scanId scan ID of batch scan response
1668 \param - isLastAp tells whether AP is last AP in batch scan response or not
1669
1670 \return - nothing
1671
1672 --------------------------------------------------------------------------*/
1673static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1674 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1675{
1676 tHddBatchScanRsp *pHead;
1677 tHddBatchScanRsp *pNode;
1678 tHddBatchScanRsp *pPrev;
1679 tHddBatchScanRsp *pTemp;
1680 tANI_U8 ssidLen;
1681
1682 /*head of hdd batch scan response queue*/
1683 pHead = pAdapter->pBatchScanRsp;
1684
1685 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1686 if (NULL == pNode)
1687 {
1688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1689 "%s: Could not allocate memory", __func__);
1690 VOS_ASSERT(0);
1691 return;
1692 }
1693
1694 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1695 sizeof(pNode->ApInfo.bssid));
1696 ssidLen = strlen(pApMetaInfo->ssid);
1697 if (SIR_MAX_SSID_SIZE < ssidLen)
1698 {
1699 /*invalid scan result*/
1700 vos_mem_free(pNode);
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1702 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1703 return;
1704 }
1705 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1706 /*null terminate ssid*/
1707 pNode->ApInfo.ssid[ssidLen] = '\0';
1708 pNode->ApInfo.ch = pApMetaInfo->ch;
1709 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1710 pNode->ApInfo.age = pApMetaInfo->timestamp;
1711 pNode->ApInfo.batchId = scanId;
1712 pNode->ApInfo.isLastAp = isLastAp;
1713
1714 pNode->pNext = NULL;
1715 if (NULL == pHead)
1716 {
1717 pAdapter->pBatchScanRsp = pNode;
1718 }
1719 else
1720 {
1721 pTemp = pHead;
1722 while (NULL != pTemp)
1723 {
1724 pPrev = pTemp;
1725 pTemp = pTemp->pNext;
1726 }
1727 pPrev->pNext = pNode;
1728 }
1729
1730 return;
1731}/*End of hdd_populate_batch_scan_rsp_queue*/
1732
1733/**---------------------------------------------------------------------------
1734
1735 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1736 receiving batch scan response indication from FW. It saves get batch scan
1737 response data in HDD batch scan response queue. This callback sets the
1738 completion event on which hdd_ioctl is waiting only after getting complete
1739 batch scan response data from FW
1740
1741 \param - callbackContext Pointer to HDD adapter
1742 \param - pRsp Pointer to get batch scan response data received from FW
1743
1744 \return - nothing
1745
1746 --------------------------------------------------------------------------*/
1747static void hdd_batch_scan_result_ind_callback
1748(
1749 void *callbackContext,
1750 void *pRsp
1751)
1752{
1753 v_BOOL_t isLastAp;
1754 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001755 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301756 tANI_U32 numberScanList;
1757 tANI_U32 nextScanListOffset;
1758 tANI_U32 nextApMetaInfoOffset;
1759 hdd_adapter_t* pAdapter;
1760 tpSirBatchScanList pScanList;
1761 tpSirBatchScanNetworkInfo pApMetaInfo;
1762 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1763 tSirSetBatchScanReq *pReq;
1764
1765 pAdapter = (hdd_adapter_t *)callbackContext;
1766 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001767 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 {
1769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "%s: Invalid pAdapter magic", __func__);
1771 VOS_ASSERT(0);
1772 return;
1773 }
1774
1775 /*initialize locals*/
1776 pReq = &pAdapter->hddSetBatchScanReq;
1777 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1778 isLastAp = FALSE;
1779 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001780 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301781 numberScanList = 0;
1782 nextScanListOffset = 0;
1783 nextApMetaInfoOffset = 0;
1784 pScanList = NULL;
1785 pApMetaInfo = NULL;
1786
1787 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1788 {
1789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001790 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301791 isLastAp = TRUE;
1792 goto done;
1793 }
1794
1795 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1797 "Batch scan rsp: numberScalList %d", numberScanList);
1798
1799 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1800 {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "%s: numberScanList %d", __func__, numberScanList);
1803 isLastAp = TRUE;
1804 goto done;
1805 }
1806
1807 while (numberScanList)
1808 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001809 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301810 nextScanListOffset);
1811 if (NULL == pScanList)
1812 {
1813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001814 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301815 isLastAp = TRUE;
1816 goto done;
1817 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001818 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001820 "Batch scan rsp: numApMetaInfo %d scanId %d",
1821 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301822
1823 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1824 {
1825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1827 isLastAp = TRUE;
1828 goto done;
1829 }
1830
Rajeev Kumarce651e42013-10-21 18:57:15 -07001831 /*Initialize next AP meta info offset for next scan list*/
1832 nextApMetaInfoOffset = 0;
1833
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 while (numApMetaInfo)
1835 {
1836 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1837 nextApMetaInfoOffset);
1838 if (NULL == pApMetaInfo)
1839 {
1840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001841 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301842 isLastAp = TRUE;
1843 goto done;
1844 }
1845 /*calculate AP age*/
1846 pApMetaInfo->timestamp =
1847 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1848
1849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001850 "%s: bssId "MAC_ADDRESS_STR
1851 " ch %d rssi %d timestamp %d", __func__,
1852 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1853 pApMetaInfo->ch, pApMetaInfo->rssi,
1854 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301855
1856 /*mark last AP in batch scan response*/
1857 if ((TRUE == pBatchScanRsp->isLastResult) &&
1858 (1 == numberScanList) && (1 == numApMetaInfo))
1859 {
1860 isLastAp = TRUE;
1861 }
1862
1863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 /*store batch scan repsonse in hdd queue*/
1865 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1866 pScanList->scanId, isLastAp);
1867 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1868
1869 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1870 numApMetaInfo--;
1871 }
1872
Rajeev Kumarce651e42013-10-21 18:57:15 -07001873 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1874 + (sizeof(tSirBatchScanNetworkInfo)
1875 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301876 numberScanList--;
1877 }
1878
1879done:
1880
1881 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1882 requested from hdd_ioctl*/
1883 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1884 (TRUE == isLastAp))
1885 {
1886 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1887 complete(&pAdapter->hdd_get_batch_scan_req_var);
1888 }
1889
1890 return;
1891}/*End of hdd_batch_scan_result_ind_callback*/
1892
1893/**---------------------------------------------------------------------------
1894
1895 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1896 response as per batch scan FR request format by putting proper markers
1897
1898 \param - pDest pointer to destination buffer
1899 \param - cur_len current length
1900 \param - tot_len total remaining size which can be written to user space
1901 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1902 \param - pAdapter Pointer to HDD adapter
1903
1904 \return - ret no of characters written
1905
1906 --------------------------------------------------------------------------*/
1907static tANI_U32
1908hdd_format_batch_scan_rsp
1909(
1910 tANI_U8 *pDest,
1911 tANI_U32 cur_len,
1912 tANI_U32 tot_len,
1913 tHddBatchScanRsp *pApMetaInfo,
1914 hdd_adapter_t* pAdapter
1915)
1916{
1917 tANI_U32 ret = 0;
1918 tANI_U32 rem_len = 0;
1919 tANI_U8 temp_len = 0;
1920 tANI_U8 temp_total_len = 0;
1921 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1922 tANI_U8 *pTemp = temp;
1923
1924 /*Batch scan reponse needs to be returned to user space in
1925 following format:
1926 "scancount=X\n" where X is the number of scans in current batch
1927 batch
1928 "trunc\n" optional present if current scan truncated
1929 "bssid=XX:XX:XX:XX:XX:XX\n"
1930 "ssid=XXXX\n"
1931 "freq=X\n" frequency in Mhz
1932 "level=XX\n"
1933 "age=X\n" ms
1934 "dist=X\n" cm (-1 if not available)
1935 "errror=X\n" (-1if not available)
1936 "====\n" (end of ap marker)
1937 "####\n" (end of scan marker)
1938 "----\n" (end of results)*/
1939 /*send scan result in above format to user space based on
1940 available length*/
1941 /*The GET response may have more data than the driver can return in its
1942 buffer. In that case the buffer should be filled to the nearest complete
1943 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1944 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1945 The final buffer should end with "----\n"*/
1946
1947 /*sanity*/
1948 if (cur_len > tot_len)
1949 {
1950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1951 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1952 return 0;
1953 }
1954 else
1955 {
1956 rem_len = (tot_len - cur_len);
1957 }
1958
1959 /*end scan marker*/
1960 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1961 {
1962 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1963 pTemp += temp_len;
1964 temp_total_len += temp_len;
1965 }
1966
1967 /*bssid*/
1968 temp_len = snprintf(pTemp, sizeof(temp),
1969 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1970 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1971 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1972 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*ssid*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1978 pApMetaInfo->ApInfo.ssid);
1979 pTemp += temp_len;
1980 temp_total_len += temp_len;
1981
1982 /*freq*/
1983 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001984 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301985 pTemp += temp_len;
1986 temp_total_len += temp_len;
1987
1988 /*level*/
1989 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1990 pApMetaInfo->ApInfo.rssi);
1991 pTemp += temp_len;
1992 temp_total_len += temp_len;
1993
1994 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001995 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301996 pApMetaInfo->ApInfo.age);
1997 pTemp += temp_len;
1998 temp_total_len += temp_len;
1999
2000 /*dist*/
2001 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2002 pTemp += temp_len;
2003 temp_total_len += temp_len;
2004
2005 /*error*/
2006 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2007 pTemp += temp_len;
2008 temp_total_len += temp_len;
2009
2010 /*end AP marker*/
2011 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2012 pTemp += temp_len;
2013 temp_total_len += temp_len;
2014
2015 /*last AP in batch scan response*/
2016 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2017 {
2018 /*end scan marker*/
2019 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2020 pTemp += temp_len;
2021 temp_total_len += temp_len;
2022
2023 /*end batch scan result marker*/
2024 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2025 pTemp += temp_len;
2026 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002027
Rajeev79dbe4c2013-10-05 11:03:42 +05302028 }
2029
2030 if (temp_total_len < rem_len)
2031 {
2032 ret = temp_total_len + 1;
2033 strlcpy(pDest, temp, ret);
2034 pAdapter->isTruncated = FALSE;
2035 }
2036 else
2037 {
2038 pAdapter->isTruncated = TRUE;
2039 if (rem_len >= strlen("%%%%"))
2040 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002041 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302042 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002043 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302044 {
2045 ret = 0;
2046 }
2047 }
2048
2049 return ret;
2050
2051}/*End of hdd_format_batch_scan_rsp*/
2052
2053/**---------------------------------------------------------------------------
2054
2055 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2056 buffer starting with head of hdd batch scan response queue
2057
2058 \param - pAdapter Pointer to HDD adapter
2059 \param - pDest Pointer to user data buffer
2060 \param - cur_len current offset in user buffer
2061 \param - rem_len remaining no of bytes in user buffer
2062
2063 \return - number of bytes written in user buffer
2064
2065 --------------------------------------------------------------------------*/
2066
2067tANI_U32 hdd_populate_user_batch_scan_rsp
2068(
2069 hdd_adapter_t* pAdapter,
2070 tANI_U8 *pDest,
2071 tANI_U32 cur_len,
2072 tANI_U32 rem_len
2073)
2074{
2075 tHddBatchScanRsp *pHead;
2076 tHddBatchScanRsp *pPrev;
2077 tANI_U32 len;
2078
Rajeev79dbe4c2013-10-05 11:03:42 +05302079 pAdapter->isTruncated = FALSE;
2080
2081 /*head of hdd batch scan response queue*/
2082 pHead = pAdapter->pBatchScanRsp;
2083 while (pHead)
2084 {
2085 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2086 pAdapter);
2087 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002088 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302089 cur_len += len;
2090 if(TRUE == pAdapter->isTruncated)
2091 {
2092 /*result is truncated return rest of scan rsp in next req*/
2093 cur_len = rem_len;
2094 break;
2095 }
2096 pPrev = pHead;
2097 pHead = pHead->pNext;
2098 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002099 if (TRUE == pPrev->ApInfo.isLastAp)
2100 {
2101 pAdapter->prev_batch_id = 0;
2102 }
2103 else
2104 {
2105 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2106 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302107 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002108 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302109 }
2110
2111 return cur_len;
2112}/*End of hdd_populate_user_batch_scan_rsp*/
2113
2114/**---------------------------------------------------------------------------
2115
2116 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2117 scan response data from HDD queue to user space
2118 It does following in detail:
2119 a) if HDD has enough data in its queue then it 1st copies data to user
2120 space and then send get batch scan indication message to FW. In this
2121 case it does not wait on any event and batch scan response data will
2122 be populated in HDD response queue in MC thread context after receiving
2123 indication from FW
2124 b) else send get batch scan indication message to FW and wait on an event
2125 which will be set once HDD receives complete batch scan response from
2126 FW and then this function returns batch scan response to user space
2127
2128 \param - pAdapter Pointer to HDD adapter
2129 \param - pPrivData Pointer to priv_data
2130
2131 \return - 0 for success -EFAULT for failure
2132
2133 --------------------------------------------------------------------------*/
2134
2135int hdd_return_batch_scan_rsp_to_user
2136(
2137 hdd_adapter_t* pAdapter,
2138 hdd_priv_data_t *pPrivData,
2139 tANI_U8 *command
2140)
2141{
2142 tANI_U8 *pDest;
2143 tANI_U32 count = 0;
2144 tANI_U32 len = 0;
2145 tANI_U32 cur_len = 0;
2146 tANI_U32 rem_len = 0;
2147 eHalStatus halStatus;
2148 unsigned long rc;
2149 tSirTriggerBatchScanResultInd *pReq;
2150
2151 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2152 pReq->param = 0;/*batch scan client*/
2153 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2154 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2155
2156 cur_len = pPrivData->used_len;
2157 if (pPrivData->total_len > pPrivData->used_len)
2158 {
2159 rem_len = pPrivData->total_len - pPrivData->used_len;
2160 }
2161 else
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: Invalid user data buffer total_len %d used_len %d",
2165 __func__, pPrivData->total_len, pPrivData->used_len);
2166 return -EFAULT;
2167 }
2168
2169 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2170 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2171 cur_len, rem_len);
2172 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2173
2174 /*enough scan result available in cache to return to user space or
2175 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002176 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302177 {
2178 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2179 halStatus = sme_TriggerBatchScanResultInd(
2180 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2181 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2182 pAdapter);
2183 if ( eHAL_STATUS_SUCCESS == halStatus )
2184 {
2185 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2186 {
2187 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2188 rc = wait_for_completion_timeout(
2189 &pAdapter->hdd_get_batch_scan_req_var,
2190 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302191 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302192 {
2193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302194 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2195 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 return -EFAULT;
2197 }
2198 }
2199
2200 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002201 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 pDest += len;
2203 cur_len += len;
2204
2205 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2206 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2207 cur_len, rem_len);
2208 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2209
2210 count = 0;
2211 len = (len - pPrivData->used_len);
2212 pDest = (command + pPrivData->used_len);
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002214 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 while(count < len)
2216 {
2217 printk("%c", *(pDest + count));
2218 count++;
2219 }
2220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2221 "%s: copy %d data to user buffer", __func__, len);
2222 if (copy_to_user(pPrivData->buf, pDest, len))
2223 {
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 "%s: failed to copy data to user buffer", __func__);
2226 return -EFAULT;
2227 }
2228 }
2229 else
2230 {
2231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2232 "sme_GetBatchScanScan returned failure halStatus %d",
2233 halStatus);
2234 return -EINVAL;
2235 }
2236 }
2237 else
2238 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302239 count = 0;
2240 len = (len - pPrivData->used_len);
2241 pDest = (command + pPrivData->used_len);
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002243 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 while(count < len)
2245 {
2246 printk("%c", *(pDest + count));
2247 count++;
2248 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2250 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302251 if (copy_to_user(pPrivData->buf, pDest, len))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2254 "%s: failed to copy data to user buffer", __func__);
2255 return -EFAULT;
2256 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302257 }
2258
2259 return 0;
2260} /*End of hdd_return_batch_scan_rsp_to_user*/
2261
Rajeev Kumar8b373292014-01-08 20:36:55 -08002262/**---------------------------------------------------------------------------
2263
2264 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2265 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2266 WLS_BATCHING VERSION
2267 WLS_BATCHING SET
2268 WLS_BATCHING GET
2269 WLS_BATCHING STOP
2270
2271 \param - pAdapter Pointer to HDD adapter
2272 \param - pPrivdata Pointer to priv_data
2273 \param - command Pointer to command
2274
2275 \return - 0 for success -EFAULT for failure
2276
2277 --------------------------------------------------------------------------*/
2278
2279int hdd_handle_batch_scan_ioctl
2280(
2281 hdd_adapter_t *pAdapter,
2282 hdd_priv_data_t *pPrivdata,
2283 tANI_U8 *command
2284)
2285{
2286 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002287 hdd_context_t *pHddCtx;
2288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302289 ENTER();
2290
Yue Mae36e3552014-03-05 17:06:20 -08002291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2292 ret = wlan_hdd_validate_context(pHddCtx);
2293 if (ret)
2294 {
Yue Mae36e3552014-03-05 17:06:20 -08002295 goto exit;
2296 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002297
2298 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2299 {
2300 char extra[32];
2301 tANI_U8 len = 0;
2302 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2303
2304 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2305 {
2306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2307 "%s: Batch scan feature is not supported by FW", __func__);
2308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
2312 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2313 version);
2314 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2315 {
2316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2317 "%s: failed to copy data to user buffer", __func__);
2318 ret = -EFAULT;
2319 goto exit;
2320 }
2321 ret = HDD_BATCH_SCAN_VERSION;
2322 }
2323 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2324 {
2325 int status;
2326 tANI_U8 *value = (command + 16);
2327 eHalStatus halStatus;
2328 unsigned long rc;
2329 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2330 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2331
2332 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2333 {
2334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2335 "%s: Batch scan feature is not supported by FW", __func__);
2336 ret = -EINVAL;
2337 goto exit;
2338 }
2339
2340 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2341 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2342 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2343 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2344 {
2345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302346 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002347 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302348 hdd_device_modetoString(pAdapter->device_mode),
2349 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002350 ret = -EINVAL;
2351 goto exit;
2352 }
2353
2354 status = hdd_parse_set_batchscan_command(value, pReq);
2355 if (status)
2356 {
2357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2358 "Invalid WLS_BATCHING SET command");
2359 ret = -EINVAL;
2360 goto exit;
2361 }
2362
2363
2364 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2365 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2366 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2367 pAdapter);
2368
2369 if ( eHAL_STATUS_SUCCESS == halStatus )
2370 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302371 char extra[32];
2372 tANI_U8 len = 0;
2373 tANI_U8 mScan = 0;
2374
Rajeev Kumar8b373292014-01-08 20:36:55 -08002375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2376 "sme_SetBatchScanReq returned success halStatus %d",
2377 halStatus);
2378 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2379 {
2380 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2381 rc = wait_for_completion_timeout(
2382 &pAdapter->hdd_set_batch_scan_req_var,
2383 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2384 if (0 == rc)
2385 {
2386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2387 "%s: Timeout waiting for set batch scan to complete",
2388 __func__);
2389 ret = -EINVAL;
2390 goto exit;
2391 }
2392 }
2393 if ( !pRsp->nScansToBatch )
2394 {
2395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2396 "%s: Received set batch scan failure response from FW",
2397 __func__);
2398 ret = -EINVAL;
2399 goto exit;
2400 }
2401 /*As per the Batch Scan Framework API we should return the MIN of
2402 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302403 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002404
2405 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2406
2407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302409 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2410 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2411 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2412 {
2413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2414 "%s: failed to copy MSCAN value to user buffer", __func__);
2415 ret = -EFAULT;
2416 goto exit;
2417 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002418 }
2419 else
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "sme_SetBatchScanReq returned failure halStatus %d",
2423 halStatus);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427 }
2428 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2429 {
2430 eHalStatus halStatus;
2431 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2432 pInd->param = 0;
2433
2434 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 "%s: Batch scan feature is not supported by FW", __func__);
2438 ret = -EINVAL;
2439 goto exit;
2440 }
2441
2442 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2443 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002445 "Batch scan is not yet enabled batch scan state %d",
2446 pAdapter->batchScanState);
2447 ret = -EINVAL;
2448 goto exit;
2449 }
2450
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002451 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2452 hdd_deinit_batch_scan(pAdapter);
2453 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2454
Rajeev Kumar8b373292014-01-08 20:36:55 -08002455 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2456
2457 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2458 pAdapter->sessionId);
2459 if ( eHAL_STATUS_SUCCESS == halStatus )
2460 {
2461 ret = 0;
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2463 "sme_StopBatchScanInd returned success halStatus %d",
2464 halStatus);
2465 }
2466 else
2467 {
2468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2469 "sme_StopBatchScanInd returned failure halStatus %d",
2470 halStatus);
2471 ret = -EINVAL;
2472 goto exit;
2473 }
2474 }
2475 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2476 {
2477 tANI_U32 remain_len;
2478
2479 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "%s: Batch scan feature is not supported by FW", __func__);
2483 ret = -EINVAL;
2484 goto exit;
2485 }
2486
2487 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2488 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002490 "Batch scan is not yet enabled could not return results"
2491 "Batch Scan state %d",
2492 pAdapter->batchScanState);
2493 ret = -EINVAL;
2494 goto exit;
2495 }
2496
2497 pPrivdata->used_len = 16;
2498 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2499 if (remain_len < pPrivdata->total_len)
2500 {
2501 /*Clear previous batch scan response data if any*/
2502 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2503 }
2504 else
2505 {
2506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2507 "Invalid total length from user space can't fetch batch"
2508 " scan response total_len %d used_len %d remain len %d",
2509 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2510 ret = -EINVAL;
2511 goto exit;
2512 }
2513 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2514 }
2515
2516exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302517 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002518 return ret;
2519}
2520
2521
Rajeev79dbe4c2013-10-05 11:03:42 +05302522#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2523
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302524#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2525/**
2526 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2527 * to Handoff request
2528 * @handoffInfo: Pointer to Handoff request
2529 * @src: enum of handoff_src
2530 * Return: None
2531 */
2532#ifndef QCA_WIFI_ISOC
2533static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2534 *handoffInfo, handoff_src src)
2535{
2536 handoffInfo->src = src;
2537}
2538#else
2539static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2540 *handoffInfo, handoff_src src)
2541{
2542}
2543#endif
2544
2545/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302546 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302547 *
2548 * @pAdapter: Adapter upon which the command was received
2549 * @bssid: BSSID with which to reassociate
2550 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552 *
2553 * Return: 0 for success non-zero for failure
2554 */
2555#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302556int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302557 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302558{
2559 hdd_station_ctx_t *pHddStaCtx;
2560 tCsrHandoffRequest handoffInfo;
2561 hdd_context_t *pHddCtx = NULL;
2562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2563
2564 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2565
2566 /* if not associated, no need to proceed with reassoc */
2567 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2568 hddLog(LOG1, FL("Not associated"));
2569 return -EINVAL;
2570 }
2571
2572 /* if the target bssid is same as currently associated AP,
2573 then no need to proceed with reassoc */
2574 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2575 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2576 return -EINVAL;
2577 }
2578
2579 /* Check channel number is a valid channel number */
2580 if (VOS_STATUS_SUCCESS !=
2581 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2582 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2583 return -EINVAL;
2584 }
2585
2586 /* Proceed with reassoc */
2587 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302588 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302589 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2590 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2591 return 0;
2592}
2593#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302594int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302595 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302596{
2597 return -EPERM;
2598}
2599#endif
2600
2601/**
2602 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2603 * This function parses the v1 REASSOC command with the format
2604 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2605 * Hex-ASCII representation of the BSSID and CH is the ASCII
2606 * representation of the channel. For example
2607 * REASSOC 00:0a:0b:11:22:33 48
2608 *
2609 * @pAdapter: Adapter upon which the command was received
2610 * @command: ASCII text command that was received
2611 *
2612 * Return: 0 for success non-zero for failure
2613 */
2614static int
2615hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2616{
2617 tANI_U8 channel = 0;
2618 tSirMacAddr bssid;
2619 int ret;
2620
2621 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2622 if (ret)
2623 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2624 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302625 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302626
2627 return ret;
2628}
2629
2630/**
2631 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2632 * This function parses the v2 REASSOC command with the format
2633 * REASSOC <android_wifi_reassoc_params>
2634 *
2635 * @pAdapter: Adapter upon which the command was received
2636 * @command: command that was received, ASCII command followed
2637 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302638 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302639 *
2640 * Return: 0 for success non-zero for failure
2641 */
2642static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2644 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302645{
2646 struct android_wifi_reassoc_params params;
2647 tSirMacAddr bssid;
2648 int ret;
2649
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302650 if (total_len < sizeof(params) + 8) {
2651 hddLog(LOGE, FL("Invalid command length"));
2652 return -EINVAL;
2653 }
2654
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302655 /* The params are located after "REASSOC " */
2656 memcpy(&params, command + 8, sizeof(params));
2657
2658 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2659 hddLog(LOGE, FL("MAC address parsing failed"));
2660 ret = -EINVAL;
2661 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302662 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302663 }
2664 return ret;
2665}
2666
2667/**
2668 * hdd_parse_reassoc() - parse the REASSOC command
2669 * There are two different versions of the REASSOC command.Version 1
2670 * of the command contains a parameter list that is ASCII characters
2671 * whereas version 2 contains a combination of ASCII and binary
2672 * payload. Determine if a version 1 or a version 2 command is being
2673 * parsed by examining the parameters, and then dispatch the parser
2674 * that is appropriate for the command.
2675 *
2676 * @pAdapter: Adapter upon which the command was received
2677 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302678 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302679 *
2680 * Return: 0 for success non-zero for failure
2681 */
2682static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302683hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302684{
2685 int ret;
2686
2687 /*
2688 * both versions start with "REASSOC"
2689 * v1 has a bssid and channel # as an ASCII string
2690 * REASSOC xx:xx:xx:xx:xx:xx CH
2691 * v2 has a C struct
2692 * REASSOC <binary c struct>
2693 *
2694 * The first field in the v2 struct is also the bssid in ASCII.
2695 * But in the case of a v2 message the BSSID is NUL-terminated.
2696 * Hence we can peek at that offset to see if this is V1 or V2
2697 * REASSOC xx:xx:xx:xx:xx:xx*
2698 * 1111111111222222
2699 * 01234567890123456789012345
2700 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302701
2702 if (total_len < 26) {
2703 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2704 return -EINVAL;
2705 }
2706
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302707 if (command[25])
2708 ret = hdd_parse_reassoc_v1(pAdapter, command);
2709 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302710 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302711
2712 return ret;
2713}
2714#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2715
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302716struct bcn_miss_rate_priv {
2717 int bcn_miss_rate;
2718};
2719
2720/**
2721 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2722 * rate from firmware
2723 * @status: Status of get beacon miss rate operation
2724 * @bcnMissRate: Beacon miss rate
2725 * @context: Context passed while registering callback
2726 *
2727 * This function is invoked by WDA layer on receiving
2728 * WDI_GET_BCN_MISS_RATE_RSP
2729 *
2730 * Return: None
2731 */
2732static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2733 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302734{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302735 struct hdd_request *request;
2736 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302737
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302738 request = hdd_request_get(context);
2739 if (!request) {
2740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2741 return;
2742 }
c_hpothu92367912014-05-01 15:18:17 +05302743
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302744 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302745
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302746 if (VOS_STATUS_SUCCESS == status)
2747 priv->bcn_miss_rate = bcnMissRate;
2748 else
2749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302750
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302751 hdd_request_complete(request);
2752 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302753
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302754 return;
c_hpothu92367912014-05-01 15:18:17 +05302755}
2756
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302757struct fw_stats_priv {
2758 tSirFwStatsResult *fw_stats;
2759};
2760
2761/**
2762 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2763 * from firmware
2764 * @status: Status of get firmware stats operation
2765 * @fwStatsResult: firmware stats
2766 * @context: Context passed while registering callback
2767 *
2768 * This function is invoked by WDA layer on receiving
2769 * WDI_GET_FW_STATS_RSP
2770 *
2771 * Return: None
2772 */
2773static void hdd_fw_stats_cb(VOS_STATUS status,
2774 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302775{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302776 struct hdd_request *request;
2777 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302778
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302779 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302780
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302781 request = hdd_request_get(context);
2782 if (!request) {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2784 return;
2785 }
2786 priv = hdd_request_priv(request);
2787
2788 if (VOS_STATUS_SUCCESS == status)
2789 *priv->fw_stats = *fwStatsResult;
2790 else
2791 priv->fw_stats = NULL;
2792
2793 hdd_request_complete(request);
2794 hdd_request_put(request);
2795 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302796}
2797
jge35567202017-06-21 16:39:38 +08002798/*
2799 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2800 *@pValue Pointer to MAXTXPOWER command
2801 *@pTxPower Pointer to tx power
2802 *
2803 *This function parses the MAXTXPOWER command passed in the format
2804 * MAXTXPOWER<space>X(Tx power in dbm)
2805 * For example input commands:
2806 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2807 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2808 *
2809 *return - 0 for success non-zero for failure
2810 */
2811static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2812{
2813 unsigned char *inPtr = pValue;
2814 int tempInt;
2815 int v = 0;
2816 *pTxPower = 0;
2817
2818 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2819 /* no argument after the command */
2820 if (NULL == inPtr)
2821 return -EINVAL;
2822 /* no space after the command */
2823 else if (SPACE_ASCII_VALUE != *inPtr)
2824 return -EINVAL;
2825
2826 /* removing empty spaces */
2827 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2828
2829 /* no argument followed by spaces */
2830 if ('\0' == *inPtr)
2831 return 0;
2832
2833 v = kstrtos32(inPtr, 10, &tempInt);
2834
2835 /* Range checking for passed parameter */
2836 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2837 return -EINVAL;
2838
2839 *pTxPower = tempInt;
2840
2841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2842 "SETMAXTXPOWER: %d", *pTxPower);
2843
2844 return 0;
2845}
2846
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302847static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2848{
2849 int ret = 0;
2850
2851 if (!pCfg || !command || !extra || !len)
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2855 ret = -EINVAL;
2856 return ret;
2857 }
2858
2859 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2860 {
2861 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2862 (int)pCfg->nActiveMaxChnTime);
2863 return ret;
2864 }
2865 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2866 {
2867 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2868 (int)pCfg->nActiveMinChnTime);
2869 return ret;
2870 }
2871 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2872 {
2873 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2874 (int)pCfg->nPassiveMaxChnTime);
2875 return ret;
2876 }
2877 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2878 {
2879 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2880 (int)pCfg->nPassiveMinChnTime);
2881 return ret;
2882 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302883 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2884 {
2885 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2886 (int)pCfg->nActiveMaxChnTime);
2887 return ret;
2888 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302889 else
2890 {
2891 ret = -EINVAL;
2892 }
2893
2894 return ret;
2895}
2896
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302897/**
2898 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2899 * @pCfg: Pointer to HDD context
2900 * @command: ASCII text command that is received
2901 * @extra: Pointer to copy data sent to user
2902 * @n: size of 'extra' buffer
2903 * @len: length copied to 'extra' buffer
2904 *
2905 * Driver commands:
2906 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2907 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2908 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2909 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2910 *
2911 * Return: 0 for success non-zero for failure
2912 */
2913
2914static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2915 char *extra, tANI_U8 n, tANI_U8 *len)
2916{
2917 int ret = 0;
2918
2919 if (!pCfg || !command || !extra || !len)
2920 {
2921 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2922 ret = -EINVAL;
2923 return ret;
2924 }
2925
2926 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2927 {
2928 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2929 (int)pCfg->max_chntime_btc_esco);
2930 return ret;
2931 }
2932 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2933 {
2934 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2935 (int)pCfg->min_chntime_btc_esco);
2936 return ret;
2937 }
2938 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2939 {
2940 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2941 (int)pCfg->max_chntime_btc_sco);
2942 return ret;
2943 }
2944 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2945 {
2946 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2947 (int)pCfg->min_chntime_btc_sco);
2948 return ret;
2949 }
2950 else
2951 {
2952 ret = -EINVAL;
2953 }
2954
2955 return ret;
2956}
2957
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302958int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2959{
2960 if (command[len] != ' ')
2961 return -EINVAL;
2962
2963 return 0;
2964}
2965
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302966#ifdef WLAN_AP_STA_CONCURRENCY
2967
2968/**
2969 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2970 * @pCfg: Pointer to HDD context
2971 * @command: ASCII text command that is received
2972 * @extra: Pointer to copy data sent to user
2973 * @n: size of 'extra' buffer
2974 * @len: length copied to 'extra' buffer
2975 *
2976 * Driver commands:
2977 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2978 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2979 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2980 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2981 *
2982 * Return: 0 for success non-zero for failure
2983 */
2984
2985static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2986 char *extra, tANI_U8 n, tANI_U8 *len)
2987{
2988 int ret = 0;
2989
2990 if (!pCfg || !command || !extra || !len)
2991 {
2992 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2993 ret = -EINVAL;
2994 return ret;
2995 }
2996
2997 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2998 {
2999 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3000 (int)pCfg->nActiveMaxChnTimeConc);
3001 return ret;
3002 }
3003 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3004 {
3005 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3006 (int)pCfg->nActiveMinChnTimeConc);
3007 return ret;
3008 }
3009 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3010 {
3011 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3012 (int)pCfg->nPassiveMaxChnTimeConc);
3013 return ret;
3014 }
3015 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3016 {
3017 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3018 (int)pCfg->nPassiveMinChnTimeConc);
3019 return ret;
3020 }
3021 else
3022 {
3023 ret = -EINVAL;
3024 }
3025
3026 return ret;
3027}
3028
3029/**
3030 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3031 * @pAdapter: Adapter upon which the command was received
3032 * @command: ASCII text command that is received
3033 *
3034 * Driver commands:
3035 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3036 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3037 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3038 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3039 *
3040 * Return: 0 for success non-zero for failure
3041 */
3042
3043static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3044{
3045 tHalHandle hHal;
3046 hdd_config_t *pCfg;
3047 tANI_U8 *value = command;
3048 int val = 0, ret = 0, temp = 0;
3049 tSmeConfigParams smeConfig;
3050
3051 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3052 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3053 {
3054 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3055 ret = -EINVAL;
3056 return ret;
3057 }
3058
3059 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3060 sme_GetConfigParam(hHal, &smeConfig);
3061
3062 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3063 {
3064 if (hdd_drv_cmd_validate(command, 27)) {
3065 hddLog(LOGE, FL("Invalid driver command"));
3066 return -EINVAL;
3067 }
3068
3069 value = value + 28;
3070 temp = kstrtou32(value, 10, &val);
3071 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3072 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3073 {
3074 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3075 ret = -EFAULT;
3076 return ret;
3077 }
3078 pCfg->nActiveMaxChnTimeConc = val;
3079 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3080 sme_UpdateConfig(hHal, &smeConfig);
3081 }
3082 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3083 {
3084 if (hdd_drv_cmd_validate(command, 27)) {
3085 hddLog(LOGE, FL("Invalid driver command"));
3086 return -EINVAL;
3087 }
3088
3089 value = value + 28;
3090 temp = kstrtou32(value, 10, &val);
3091 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3092 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3093 {
3094 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3095 ret = -EFAULT;
3096 return ret;
3097 }
3098 pCfg->nActiveMinChnTimeConc = val;
3099 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3100 sme_UpdateConfig(hHal, &smeConfig);
3101 }
3102 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3103 {
3104 if (hdd_drv_cmd_validate(command, 28)) {
3105 hddLog(LOGE, FL("Invalid driver command"));
3106 return -EINVAL;
3107 }
3108
3109 value = value + 29;
3110 temp = kstrtou32(value, 10, &val);
3111 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3112 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3113 {
3114 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3115 ret = -EFAULT;
3116 return ret;
3117 }
3118 pCfg->nPassiveMaxChnTimeConc = val;
3119 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3120 sme_UpdateConfig(hHal, &smeConfig);
3121 }
3122 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3123 {
3124 if (hdd_drv_cmd_validate(command, 28)) {
3125 hddLog(LOGE, FL("Invalid driver command"));
3126 return -EINVAL;
3127 }
3128
3129 value = value + 29;
3130 temp = kstrtou32(value, 10, &val);
3131 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3132 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3133 {
3134 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3135 ret = -EFAULT;
3136 return ret;
3137 }
3138 pCfg->nPassiveMinChnTimeConc = val;
3139 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3140 sme_UpdateConfig(hHal, &smeConfig);
3141 }
3142 else
3143 {
3144 ret = -EINVAL;
3145 }
3146
3147 return ret;
3148}
3149
3150#endif
3151
3152/**
3153 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3154 * @pAdapter: Adapter upon which the command was received
3155 * @command: ASCII text command that is received
3156 *
3157 * Driver commands:
3158 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3159 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3160 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3161 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3162 *
3163 * Return: 0 for success non-zero for failure
3164 */
3165
3166static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3167{
3168 tHalHandle hHal;
3169 hdd_config_t *pCfg;
3170 tANI_U8 *value = command;
3171 int val = 0, ret = 0, temp = 0;
3172 tSmeConfigParams smeConfig;
3173
3174 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3175 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3176 {
3177 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3178 ret = -EINVAL;
3179 return ret;
3180 }
3181
3182 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3183 sme_GetConfigParam(hHal, &smeConfig);
3184
3185 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3186 {
3187 if (hdd_drv_cmd_validate(command, 24)) {
3188 hddLog(LOGE, FL("Invalid driver command"));
3189 return -EINVAL;
3190 }
3191
3192 value = value + 25;
3193 temp = kstrtou32(value, 10, &val);
3194 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3195 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3196 {
3197 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3198 ret = -EFAULT;
3199 return ret;
3200 }
3201 pCfg->max_chntime_btc_esco = val;
3202 smeConfig.csrConfig.max_chntime_btc_esco = val;
3203 sme_UpdateConfig(hHal, &smeConfig);
3204 }
3205 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3206 {
3207 if (hdd_drv_cmd_validate(command, 24)) {
3208 hddLog(LOGE, FL("Invalid driver command"));
3209 return -EINVAL;
3210 }
3211
3212 value = value + 25;
3213 temp = kstrtou32(value, 10, &val);
3214 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3215 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3216 {
3217 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3218 ret = -EFAULT;
3219 return ret;
3220 }
3221 pCfg->min_chntime_btc_esco = val;
3222 smeConfig.csrConfig.min_chntime_btc_esco = val;
3223 sme_UpdateConfig(hHal, &smeConfig);
3224 }
3225 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3226 {
3227 if (hdd_drv_cmd_validate(command, 23)) {
3228 hddLog(LOGE, FL("Invalid driver command"));
3229 return -EINVAL;
3230 }
3231
3232 value = value + 24;
3233 temp = kstrtou32(value, 10, &val);
3234 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3235 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3236 {
3237 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3238 ret = -EFAULT;
3239 return ret;
3240 }
3241 pCfg->max_chntime_btc_sco = val;
3242 smeConfig.csrConfig.max_chntime_btc_sco = val;
3243 sme_UpdateConfig(hHal, &smeConfig);
3244 }
3245 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3246 {
3247 if (hdd_drv_cmd_validate(command, 23)) {
3248 hddLog(LOGE, FL("Invalid driver command"));
3249 return -EINVAL;
3250 }
3251
3252 value = value + 24;
3253 temp = kstrtou32(value, 10, &val);
3254 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3255 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3256 {
3257 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3258 ret = -EFAULT;
3259 return ret;
3260 }
3261 pCfg->min_chntime_btc_sco = val;
3262 smeConfig.csrConfig.min_chntime_btc_sco = val;
3263 sme_UpdateConfig(hHal, &smeConfig);
3264 }
3265 else
3266 {
3267 ret = -EINVAL;
3268 }
3269
3270 return ret;
3271}
3272
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303273static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3274{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303275 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303276 hdd_config_t *pCfg;
3277 tANI_U8 *value = command;
3278 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303279 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303280
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303281 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3282 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303283 {
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3286 ret = -EINVAL;
3287 return ret;
3288 }
3289
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303290 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3291 sme_GetConfigParam(hHal, &smeConfig);
3292
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303293 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3294 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303295 if (hdd_drv_cmd_validate(command, 23))
3296 return -EINVAL;
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 value = value + 24;
3299 temp = kstrtou32(value, 10, &val);
3300 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3301 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3305 ret = -EFAULT;
3306 return ret;
3307 }
3308 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303309 smeConfig.csrConfig.nActiveMaxChnTime = val;
3310 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303311 }
3312 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3313 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303314 if (hdd_drv_cmd_validate(command, 23))
3315 return -EINVAL;
3316
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303317 value = value + 24;
3318 temp = kstrtou32(value, 10, &val);
3319 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3320 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3324 ret = -EFAULT;
3325 return ret;
3326 }
3327 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303328 smeConfig.csrConfig.nActiveMinChnTime = val;
3329 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303330 }
3331 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3332 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 if (hdd_drv_cmd_validate(command, 24))
3334 return -EINVAL;
3335
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303336 value = value + 25;
3337 temp = kstrtou32(value, 10, &val);
3338 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3339 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3343 ret = -EFAULT;
3344 return ret;
3345 }
3346 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303347 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3348 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303349 }
3350 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3351 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303352 if (hdd_drv_cmd_validate(command, 24))
3353 return -EINVAL;
3354
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303355 value = value + 25;
3356 temp = kstrtou32(value, 10, &val);
3357 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3358 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3362 ret = -EFAULT;
3363 return ret;
3364 }
3365 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303366 smeConfig.csrConfig.nPassiveMinChnTime = val;
3367 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303368 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303369 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3370 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303371 if (hdd_drv_cmd_validate(command, 12))
3372 return -EINVAL;
3373
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303374 value = value + 13;
3375 temp = kstrtou32(value, 10, &val);
3376 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3377 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3378 {
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3381 ret = -EFAULT;
3382 return ret;
3383 }
3384 pCfg->nActiveMaxChnTime = val;
3385 smeConfig.csrConfig.nActiveMaxChnTime = val;
3386 sme_UpdateConfig(hHal, &smeConfig);
3387 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303388 else
3389 {
3390 ret = -EINVAL;
3391 }
3392
3393 return ret;
3394}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303395static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3396 tANI_U8 cmd_len)
3397{
3398 tANI_U8 *value;
3399 tANI_U8 fcc_constraint;
3400
3401 eHalStatus status;
3402 int ret = 0;
3403 value = cmd + cmd_len + 1;
3404
3405 ret = kstrtou8(value, 10, &fcc_constraint);
3406 if ((ret < 0) || (fcc_constraint > 1)) {
3407 /*
3408 * If the input value is greater than max value of datatype,
3409 * then also it is a failure
3410 */
3411 hddLog(VOS_TRACE_LEVEL_ERROR,
3412 "%s: value out of range", __func__);
3413 return -EINVAL;
3414 }
3415
Agrawal Ashish842eea82016-02-04 17:56:16 +05303416 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3417 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303418 if (status != eHAL_STATUS_SUCCESS)
3419 ret = -EPERM;
3420
3421 return ret;
3422}
3423
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303424/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303425
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303426 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3427 FW will send *ONE* CA ind to Host(even though it is duplicate).
3428 When Host send IOCTL (disable), FW doesn't perform any action.
3429 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3430 sends CA ind to host. (regard less of IOCTL status)
3431 \param - pHddCtx - HDD context
3432 \param - command - command received from framework
3433 \param - cmd_len - len of the command
3434
3435 \return - 0 on success, appropriate error values on failure.
3436
3437 --------------------------------------------------------------------------*/
3438int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3439{
3440 tANI_U8 set_value;
3441 int ret = 0;
3442 eHalStatus status;
3443
3444 ret = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != ret)
3446 {
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3452 {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3454 " ini param to control channel avooidance indication");
3455 ret = 0;
3456 goto exit;
3457 }
3458
3459 set_value = command[cmd_len + 1] - '0';
3460 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3461 if (status != eHAL_STATUS_SUCCESS)
3462 {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3464 " enableDisableChanAoidance command to SME\n", __func__);
3465 ret = -EINVAL;
3466 }
3467
3468exit:
3469 return ret;
3470}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303471
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303472/**
3473 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3474 * @pHddCtx: Pointer to the HDD context
3475 * @channel: channel to reassociate
3476 * @targetApBssid: Target AP/BSSID to reassociate
3477 *
3478 * Return: None
3479 */
3480#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3481static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3482 uint8_t channel, tSirMacAddr targetApBssid)
3483{
3484 tCsrHandoffRequest handoffInfo;
3485 handoffInfo.channel = channel;
3486 handoffInfo.src = FASTREASSOC;
3487 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3488 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3489}
3490#else
3491static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3492 uint8_t channel, tSirMacAddr targetApBssid)
3493{
3494}
3495#endif
3496
3497/**
3498 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3499 * @pAdapter: Pointer to HDD adapter
3500 * @channel: Channel to scan/roam
3501 * @targetApBssid: BSSID to roam
3502 *
3503 * Return: None
3504 */
3505#ifdef QCA_WIFI_ISOC
3506static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3507 uint8_t channel, tSirMacAddr targetApBssid)
3508{
3509 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3510 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3511}
3512#else
3513static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3514 uint8_t channel, tSirMacAddr targetApBssid)
3515{
3516}
3517#endif
3518
3519/**
3520 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3521 * @pAdapter: pointer to hdd adapter
3522 * @command: pointer to the command received
3523 *
3524 * Return: VOS_STATUS enum
3525 */
3526static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3527 uint8_t *command)
3528{
3529 tANI_U8 *value = command;
3530 tANI_U8 channel = 0;
3531 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303532 hdd_station_ctx_t *pHddStaCtx = NULL;
3533 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303534 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303535 tCsrRoamModifyProfileFields mod_profile_fields;
3536 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303537 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3539
3540 /* if not associated, no need to proceed with reassoc */
3541 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3542 hddLog(LOG1, FL("Not associated!"));
3543 return eHAL_STATUS_FAILURE;
3544 }
3545
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303546 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3547 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303548 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3549 return eHAL_STATUS_FAILURE;
3550 }
3551
3552 /* if the target bssid is same as currently associated AP,
3553 then no need to proceed with reassoc */
3554 if (vos_mem_compare(targetApBssid,
3555 pHddStaCtx->conn_info.bssId,
3556 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303557 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3558 &mod_profile_fields);
3559 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3560 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303561 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303562 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303563 }
3564
3565 /* Check channel number is a valid channel number */
3566 if (VOS_STATUS_SUCCESS !=
3567 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3568 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3569 return eHAL_STATUS_FAILURE;
3570 }
3571
3572 /* Proceed with reassoc */
3573 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3574
3575 /* Proceed with scan/roam */
3576 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3577
3578 return eHAL_STATUS_SUCCESS;
3579}
3580
3581/**
3582 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3583 * @handoffInfo: Pointer to the csr Handoff Request.
3584 *
3585 * Return: None
3586 */
3587#ifndef QCA_WIFI_ISOC
3588static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3589{
3590 handoffInfo->src = REASSOC;
3591}
3592#else
3593static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3594{
3595}
3596#endif
3597
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303598/**
3599 * wlan_hdd_free_cache_channels() - Free the cache channels list
3600 * @hdd_ctx: Pointer to HDD context
3601 *
3602 * Return: None
3603 */
3604
3605static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3606{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303607 if(!hdd_ctx || !hdd_ctx->original_channels)
3608 return;
3609
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303610 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303611 hdd_ctx->original_channels->num_channels = 0;
3612 vos_mem_free(hdd_ctx->original_channels->channel_info);
3613 hdd_ctx->original_channels->channel_info = NULL;
3614 vos_mem_free(hdd_ctx->original_channels);
3615 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303616 mutex_unlock(&hdd_ctx->cache_channel_lock);
3617}
3618
3619/**
3620 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3621 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3622 * @hdd_ctx: Pointer to HDD context
3623 * @num_chan: Number of channels for which memory needs to
3624 * be allocated
3625 *
3626 * Return: 0 on success and error code on failure
3627 */
3628
3629int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3630{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303631 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303632 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303633 if (!hdd_ctx->original_channels) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "In %s, VOS_MALLOC_ERR", __func__);
3636 return -EINVAL;
3637 }
3638 hdd_ctx->original_channels->num_channels = num_chan;
3639 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303640 vos_mem_malloc(num_chan *
3641 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303642 if (!hdd_ctx->original_channels->channel_info) {
3643 hddLog(VOS_TRACE_LEVEL_ERROR,
3644 "In %s, VOS_MALLOC_ERR", __func__);
3645 hdd_ctx->original_channels->num_channels = 0;
3646 vos_mem_free(hdd_ctx->original_channels);
3647 hdd_ctx->original_channels = NULL;
3648 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303649 }
3650 return 0;
3651
3652}
3653
3654
3655int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3656{
3657 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3658 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3659 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303660 int j, tempInt, ret = 0, i, num_channels;
3661 int parsed_channels[MAX_CHANNEL];
3662 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303663
3664 if (NULL == pvosGCtx) {
3665 hddLog(VOS_TRACE_LEVEL_FATAL,
3666 "VOS Global Context is NULL");
3667 return -EINVAL;
3668 }
3669
3670 if (NULL == hdd_ctx) {
3671 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3672 return -EINVAL;
3673 }
3674
3675 param = strchr(ptr, ' ');
3676 /*no argument after the command*/
3677 if (NULL == param)
3678 return -EINVAL;
3679
3680 /*no space after the command*/
3681 else if (SPACE_ASCII_VALUE != *param)
3682 return -EINVAL;
3683
3684 param++;
3685
3686 /*removing empty spaces*/
3687 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3688 param++;
3689
3690 /*no argument followed by spaces*/
3691 if ('\0' == *param)
3692 return -EINVAL;
3693
3694 /*getting the first argument ie the number of channels*/
3695 if (sscanf(param, "%d ", &tempInt) != 1) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR,
3697 "%s: Cannot get number of channels from input",
3698 __func__);
3699 return -EINVAL;
3700 }
3701
3702 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3703 hddLog(VOS_TRACE_LEVEL_ERROR,
3704 "%s: Invalid Number of channel received", __func__);
3705 return -EINVAL;
3706 }
3707
3708 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3709 "%s: Number of channel to disable are: %d",
3710 __func__, tempInt);
3711
3712 if (!tempInt) {
3713 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3714 /*
3715 * Free the cache channels only when the command is
3716 * received with num channels as 0
3717 */
3718 wlan_hdd_free_cache_channels(hdd_ctx);
3719 }
3720 return 0;
3721 }
3722
3723 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303724 if (!hdd_ctx->original_channels) {
3725 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3726 ret = -ENOMEM;
3727 goto mem_alloc_failed;
3728 }
3729 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s, Invalid No of channel provided in the list",
3732 __func__);
3733 ret = -EINVAL;
3734 is_command_repeated = true;
3735 goto parse_failed;
3736 } else {
3737 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303738 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303739
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303740 num_channels = tempInt;
3741
3742 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303743 /*
3744 * param pointing to the beginning of first space
3745 * after number of channels
3746 */
3747 param = strpbrk(param, " ");
3748 /*no channel list after the number of channels argument*/
3749 if (NULL == param) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR,
3751 "%s, Invalid No of channel provided in the list",
3752 __func__);
3753 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303754 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303755 }
3756
3757 param++;
3758
3759 /*removing empty space*/
3760 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3761 param++;
3762
3763 if ('\0' == *param) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 "%s, No channel is provided in the list",
3766 __func__);
3767 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303768 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303769
3770 }
3771
3772 if (sscanf(param, "%d ", &tempInt) != 1) {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 "%s: Cannot read channel number",
3775 __func__);
3776 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303777 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303778
3779 }
3780
3781 if (!IS_CHANNEL_VALID(tempInt)) {
3782 hddLog(VOS_TRACE_LEVEL_ERROR,
3783 "%s: Invalid channel number received",
3784 __func__);
3785 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303786 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303787
3788 }
3789
3790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3791 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303792
3793 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303794 }
3795
3796 /*extra arguments check*/
3797 param = strchr(param, ' ');
3798 if (NULL != param) {
3799 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3800 param++;
3801
3802 if ('\0' != *param) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 "%s: Invalid argument received", __func__);
3805 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303806 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303807 }
3808 }
3809
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303810 /*
3811 * If command is received first time, cache the channels to
3812 * be disabled else compare the channels received in the
3813 * command with the cached channels, if channel list matches
3814 * return success otherewise return failure.
3815 */
3816 if (!is_command_repeated)
3817 for (j = 0; j < num_channels; j++)
3818 hdd_ctx->original_channels->
3819 channel_info[j].channel_num =
3820 parsed_channels[j];
3821 else {
3822 for (i = 0; i < num_channels; i++) {
3823 for (j = 0; j < num_channels; j++)
3824 if (hdd_ctx->original_channels->
3825 channel_info[i].channel_num ==
3826 parsed_channels[j])
3827 break;
3828 if (j == num_channels) {
3829 ret = -EINVAL;
3830 goto parse_failed;
3831 }
3832 }
3833 ret = 0;
3834 }
3835
3836mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303837 mutex_unlock(&hdd_ctx->cache_channel_lock);
3838 EXIT();
3839
3840 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303841
3842parse_failed:
3843 mutex_unlock(&hdd_ctx->cache_channel_lock);
3844 if (!is_command_repeated)
3845 wlan_hdd_free_cache_channels(hdd_ctx);
3846 EXIT();
3847 return ret;
3848
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303849}
3850
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303851int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303852 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303853{
3854 struct hdd_cache_channel_info *ch_list;
3855 unsigned char i, num_ch;
3856 int len = 0;
3857
3858 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303859 if (hdd_ctx->original_channels &&
3860 hdd_ctx->original_channels->num_channels &&
3861 hdd_ctx->original_channels->channel_info) {
3862 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303863
3864 len = scnprintf(buf, buf_len, "%s %hhu",
3865 "GET_DISABLE_CHANNEL_LIST", num_ch);
3866
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303867 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303868
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303869 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303870 len += scnprintf(buf + len, buf_len - len,
3871 " %d", ch_list[i].channel_num);
3872 }
3873 }
3874 mutex_unlock(&hdd_ctx->cache_channel_lock);
3875
3876 return len;
3877}
3878
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003879static int hdd_driver_command(hdd_adapter_t *pAdapter,
3880 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003881{
Jeff Johnson295189b2012-06-20 16:38:30 -07003882 hdd_priv_data_t priv_data;
3883 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303884 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3885 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003886 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303887 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303888#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3889 struct cfg80211_mgmt_tx_params params;
3890#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891
3892 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003893 /*
3894 * Note that valid pointers are provided by caller
3895 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003896
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003897 /* copy to local struct to avoid numerous changes to legacy code */
3898 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003899
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003900 if (priv_data.total_len <= 0 ||
3901 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003902 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003903 hddLog(VOS_TRACE_LEVEL_WARN,
3904 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3905 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003906 ret = -EINVAL;
3907 goto exit;
3908 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303909 status = wlan_hdd_validate_context(pHddCtx);
3910 if (0 != status)
3911 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303912 ret = -EINVAL;
3913 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303914 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003915 /* Allocate +1 for '\0' */
3916 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 if (!command)
3918 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003919 hddLog(VOS_TRACE_LEVEL_ERROR,
3920 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 ret = -ENOMEM;
3922 goto exit;
3923 }
3924
3925 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3926 {
3927 ret = -EFAULT;
3928 goto exit;
3929 }
3930
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003931 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003932 command[priv_data.total_len] = '\0';
3933
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003934 /* at one time the following block of code was conditional. braces
3935 * have been retained to avoid re-indenting the legacy code
3936 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003937 {
3938 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3939
3940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003941 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003942
3943 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3944 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303945 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3946 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3947 pAdapter->sessionId, (unsigned)
3948 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3949 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3950 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3951 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003952 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3953 sizeof(tSirMacAddr)))
3954 {
3955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003956 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003957 ret = -EFAULT;
3958 }
3959 }
Amar Singhal0974e402013-02-12 14:27:46 -08003960 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 {
Amar Singhal0974e402013-02-12 14:27:46 -08003962 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003963
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303964 ret = hdd_drv_cmd_validate(command, 7);
3965 if (ret)
3966 goto exit;
3967
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003969
3970 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003973 "%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 +05303974 if(VOS_FTM_MODE != hdd_get_conparam())
3975 {
3976 /* Change band request received */
3977 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3978 if(ret < 0)
3979 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3980 "%s: failed to set band ret=%d", __func__, ret);
3981 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003982 }
Kiet Lamf040f472013-11-20 21:15:23 +05303983 else if(strncmp(command, "SETWMMPS", 8) == 0)
3984 {
3985 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303986
3987 ret = hdd_drv_cmd_validate(command, 8);
3988 if (ret)
3989 goto exit;
3990
Kiet Lamf040f472013-11-20 21:15:23 +05303991 ret = hdd_wmmps_helper(pAdapter, ptr);
3992 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303993
3994 else if(strncmp(command, "TDLSSCAN", 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
Agarwal Ashishef54a182014-12-16 15:07:31 +05304002 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4003 }
4004
Jeff Johnson32d95a32012-09-10 13:15:23 -07004005 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4006 {
4007 char *country_code;
4008
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304009 ret = hdd_drv_cmd_validate(command, 7);
4010 if (ret)
4011 goto exit;
4012
Jeff Johnson32d95a32012-09-10 13:15:23 -07004013 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004014
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004015 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004016 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004017#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304018 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004019#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004020 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4021 (void *)(tSmeChangeCountryCallback)
4022 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304023 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004024 if (eHAL_STATUS_SUCCESS == ret)
4025 {
4026 ret = wait_for_completion_interruptible_timeout(
4027 &pAdapter->change_country_code,
4028 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4029 if (0 >= ret)
4030 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304032 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004033 }
4034 }
4035 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004036 {
4037 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004038 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004039 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004040 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004041
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004042 }
4043 /*
4044 command should be a string having format
4045 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4046 */
Amar Singhal0974e402013-02-12 14:27:46 -08004047 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004048 {
Amar Singhal0974e402013-02-12 14:27:46 -08004049 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004050
4051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004052 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004053
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004054 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004055 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304056
4057 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4058 {
4059 tANI_U8 *ptr;
4060
4061 ret = hdd_drv_cmd_validate(command, 10);
4062 if (ret)
4063 goto exit;
4064
4065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4066 "Received Command for VOWIFI mode in %s", __func__);
4067
4068 ptr = (tANI_U8*)command + 11;
4069 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4070 }
4071
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004072 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4073 {
4074 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304075 tANI_U8 *ptr;
4076
4077 ret = hdd_drv_cmd_validate(command, 14);
4078 if (ret)
4079 goto exit;
4080
4081 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004082
4083 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4085 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4086 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004087 hdd_set_wlan_suspend_mode(suspend);
4088 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004089#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4090 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4091 {
4092 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004093 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004094 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4095 eHalStatus status = eHAL_STATUS_SUCCESS;
4096
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304097 ret = hdd_drv_cmd_validate(command, 14);
4098 if (ret)
4099 goto exit;
4100
Srinivas Girigowdade697412013-02-14 16:31:48 -08004101 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4102 value = value + 15;
4103
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004104 /* Convert the value from ascii to integer */
4105 ret = kstrtos8(value, 10, &rssi);
4106 if (ret < 0)
4107 {
4108 /* If the input value is greater than max value of datatype, then also
4109 kstrtou8 fails */
4110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4111 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004112 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004113 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4114 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4115 ret = -EINVAL;
4116 goto exit;
4117 }
4118
Srinivas Girigowdade697412013-02-14 16:31:48 -08004119 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004120
Srinivas Girigowdade697412013-02-14 16:31:48 -08004121 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4122 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4123 {
4124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4125 "Neighbor lookup threshold value %d is out of range"
4126 " (Min: %d Max: %d)", lookUpThreshold,
4127 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4128 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4129 ret = -EINVAL;
4130 goto exit;
4131 }
4132
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304133 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4134 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4135 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4137 "%s: Received Command to Set Roam trigger"
4138 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4139
4140 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4141 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4142 if (eHAL_STATUS_SUCCESS != status)
4143 {
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4145 "%s: Failed to set roam trigger, try again", __func__);
4146 ret = -EPERM;
4147 goto exit;
4148 }
4149
4150 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304151 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004152 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4153 }
4154 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4155 {
4156 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4157 int rssi = (-1) * lookUpThreshold;
4158 char extra[32];
4159 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4161 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4162 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004163 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304164 len = VOS_MIN(priv_data.total_len, len + 1);
4165 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004166 {
4167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4168 "%s: failed to copy data to user buffer", __func__);
4169 ret = -EFAULT;
4170 goto exit;
4171 }
4172 }
4173 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4174 {
4175 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004176 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004177 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004178
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304179 ret = hdd_drv_cmd_validate(command, 17);
4180 if (ret)
4181 goto exit;
4182
Srinivas Girigowdade697412013-02-14 16:31:48 -08004183 /* input refresh period is in terms of seconds */
4184 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4185 value = value + 18;
4186 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004187 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004188 if (ret < 0)
4189 {
4190 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004191 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004193 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004194 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004195 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4196 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004197 ret = -EINVAL;
4198 goto exit;
4199 }
4200
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004201 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4202 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 {
4204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004205 "Roam scan period value %d is out of range"
4206 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004207 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4208 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004209 ret = -EINVAL;
4210 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304211 }
4212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4213 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4214 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004215 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004216
4217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4218 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004219 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004220
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004221 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4222 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004223 }
4224 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4225 {
4226 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4227 char extra[32];
4228 tANI_U8 len = 0;
4229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4231 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4232 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004233 len = scnprintf(extra, sizeof(extra), "%s %d",
4234 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004235 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304236 len = VOS_MIN(priv_data.total_len, len + 1);
4237 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4239 "%s: failed to copy data to user buffer", __func__);
4240 ret = -EFAULT;
4241 goto exit;
4242 }
4243 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004244 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4245 {
4246 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004247 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004248 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004249
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304250 ret = hdd_drv_cmd_validate(command, 24);
4251 if (ret)
4252 goto exit;
4253
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004254 /* input refresh period is in terms of seconds */
4255 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4256 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004257
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004258 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004259 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004260 if (ret < 0)
4261 {
4262 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004263 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004265 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004266 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004267 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4268 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4269 ret = -EINVAL;
4270 goto exit;
4271 }
4272
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004273 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4274 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4275 {
4276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4277 "Neighbor scan results refresh period value %d is out of range"
4278 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4279 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4280 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4281 ret = -EINVAL;
4282 goto exit;
4283 }
4284 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4285
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4287 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004288 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004289
4290 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4291 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4292 }
4293 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4294 {
4295 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4296 char extra[32];
4297 tANI_U8 len = 0;
4298
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004299 len = scnprintf(extra, sizeof(extra), "%s %d",
4300 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004301 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304302 len = VOS_MIN(priv_data.total_len, len + 1);
4303 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4305 "%s: failed to copy data to user buffer", __func__);
4306 ret = -EFAULT;
4307 goto exit;
4308 }
4309 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004310#ifdef FEATURE_WLAN_LFR
4311 /* SETROAMMODE */
4312 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4313 {
4314 tANI_U8 *value = command;
4315 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4316
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304317 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4318 hddLog(LOGE,
4319 FL("Roaming is always disabled in STA + MON concurrency"));
4320 ret = -EINVAL;
4321 goto exit;
4322 }
4323
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304324 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4325 if (ret)
4326 goto exit;
4327
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004328 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4329 value = value + SIZE_OF_SETROAMMODE + 1;
4330
4331 /* Convert the value from ascii to integer */
4332 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4333 if (ret < 0)
4334 {
4335 /* If the input value is greater than max value of datatype, then also
4336 kstrtou8 fails */
4337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4338 "%s: kstrtou8 failed range [%d - %d]", __func__,
4339 CFG_LFR_FEATURE_ENABLED_MIN,
4340 CFG_LFR_FEATURE_ENABLED_MAX);
4341 ret = -EINVAL;
4342 goto exit;
4343 }
4344 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4345 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4346 {
4347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4348 "Roam Mode value %d is out of range"
4349 " (Min: %d Max: %d)", roamMode,
4350 CFG_LFR_FEATURE_ENABLED_MIN,
4351 CFG_LFR_FEATURE_ENABLED_MAX);
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355
4356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4357 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4358 /*
4359 * Note that
4360 * SETROAMMODE 0 is to enable LFR while
4361 * SETROAMMODE 1 is to disable LFR, but
4362 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4363 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4364 */
4365 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4366 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4367 else
4368 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4369
4370 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4371 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4372 }
4373 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304374 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004375 {
4376 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4377 char extra[32];
4378 tANI_U8 len = 0;
4379
4380 /*
4381 * roamMode value shall be inverted because the sementics is different.
4382 */
4383 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4384 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4385 else
4386 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4387
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004388 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304389 len = VOS_MIN(priv_data.total_len, len + 1);
4390 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4392 "%s: failed to copy data to user buffer", __func__);
4393 ret = -EFAULT;
4394 goto exit;
4395 }
4396 }
4397#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004398#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004399#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004400 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4401 {
4402 tANI_U8 *value = command;
4403 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4404
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304405 ret = hdd_drv_cmd_validate(command, 12);
4406 if (ret)
4407 goto exit;
4408
Srinivas Girigowdade697412013-02-14 16:31:48 -08004409 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4410 value = value + 13;
4411 /* Convert the value from ascii to integer */
4412 ret = kstrtou8(value, 10, &roamRssiDiff);
4413 if (ret < 0)
4414 {
4415 /* If the input value is greater than max value of datatype, then also
4416 kstrtou8 fails */
4417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4418 "%s: kstrtou8 failed range [%d - %d]", __func__,
4419 CFG_ROAM_RSSI_DIFF_MIN,
4420 CFG_ROAM_RSSI_DIFF_MAX);
4421 ret = -EINVAL;
4422 goto exit;
4423 }
4424
4425 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4426 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4427 {
4428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4429 "Roam rssi diff value %d is out of range"
4430 " (Min: %d Max: %d)", roamRssiDiff,
4431 CFG_ROAM_RSSI_DIFF_MIN,
4432 CFG_ROAM_RSSI_DIFF_MAX);
4433 ret = -EINVAL;
4434 goto exit;
4435 }
4436
4437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4438 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4439
4440 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4441 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4442 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304443 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004444 {
4445 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4446 char extra[32];
4447 tANI_U8 len = 0;
4448
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304449 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4450 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4451 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004452 len = scnprintf(extra, sizeof(extra), "%s %d",
4453 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304454 len = VOS_MIN(priv_data.total_len, len + 1);
4455 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4457 "%s: failed to copy data to user buffer", __func__);
4458 ret = -EFAULT;
4459 goto exit;
4460 }
4461 }
4462#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004464 else if (strncmp(command, "GETBAND", 7) == 0)
4465 {
4466 int band = -1;
4467 char extra[32];
4468 tANI_U8 len = 0;
4469 hdd_getBand_helper(pHddCtx, &band);
4470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4472 TRACE_CODE_HDD_GETBAND_IOCTL,
4473 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004474 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304475 len = VOS_MIN(priv_data.total_len, len + 1);
4476 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4478 "%s: failed to copy data to user buffer", __func__);
4479 ret = -EFAULT;
4480 goto exit;
4481 }
4482 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004483 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4484 {
4485 tANI_U8 *value = command;
4486 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4487 tANI_U8 numChannels = 0;
4488 eHalStatus status = eHAL_STATUS_SUCCESS;
4489
4490 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4491 if (eHAL_STATUS_SUCCESS != status)
4492 {
4493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4494 "%s: Failed to parse channel list information", __func__);
4495 ret = -EINVAL;
4496 goto exit;
4497 }
4498
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304499 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4500 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4501 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004502 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4503 {
4504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4505 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4506 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4507 ret = -EINVAL;
4508 goto exit;
4509 }
4510 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4511 numChannels);
4512 if (eHAL_STATUS_SUCCESS != status)
4513 {
4514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4515 "%s: Failed to update channel list information", __func__);
4516 ret = -EINVAL;
4517 goto exit;
4518 }
4519 }
4520 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4521 {
4522 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4523 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004524 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004525 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004526 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004527
4528 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4529 ChannelList, &numChannels ))
4530 {
4531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4532 "%s: failed to get roam scan channel list", __func__);
4533 ret = -EFAULT;
4534 goto exit;
4535 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304536 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4537 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4538 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004539 /* output channel list is of the format
4540 [Number of roam scan channels][Channel1][Channel2]... */
4541 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004542 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304543 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004544 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004545 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4546 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004547 }
4548
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304549 len = VOS_MIN(priv_data.total_len, len + 1);
4550 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004551 {
4552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4553 "%s: failed to copy data to user buffer", __func__);
4554 ret = -EFAULT;
4555 goto exit;
4556 }
4557 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004558 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4559 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004560 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004561 char extra[32];
4562 tANI_U8 len = 0;
4563
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004564 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004565 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004566 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004567 hdd_is_okc_mode_enabled(pHddCtx) &&
4568 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4569 {
4570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004571 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004572 " hence this operation is not permitted!", __func__);
4573 ret = -EPERM;
4574 goto exit;
4575 }
4576
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004577 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004578 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304579 len = VOS_MIN(priv_data.total_len, len + 1);
4580 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "%s: failed to copy data to user buffer", __func__);
4584 ret = -EFAULT;
4585 goto exit;
4586 }
4587 }
4588 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4589 {
4590 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4591 char extra[32];
4592 tANI_U8 len = 0;
4593
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004595 then this operation is not permitted (return FAILURE) */
4596 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004598 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4599 {
4600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004601 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004602 " hence this operation is not permitted!", __func__);
4603 ret = -EPERM;
4604 goto exit;
4605 }
4606
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004607 len = scnprintf(extra, sizeof(extra), "%s %d",
4608 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304609 len = VOS_MIN(priv_data.total_len, len + 1);
4610 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004611 {
4612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4613 "%s: failed to copy data to user buffer", __func__);
4614 ret = -EFAULT;
4615 goto exit;
4616 }
4617 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004618 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004619 {
4620 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4621 char extra[32];
4622 tANI_U8 len = 0;
4623
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004624 len = scnprintf(extra, sizeof(extra), "%s %d",
4625 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304626 len = VOS_MIN(priv_data.total_len, len + 1);
4627 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004628 {
4629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4630 "%s: failed to copy data to user buffer", __func__);
4631 ret = -EFAULT;
4632 goto exit;
4633 }
4634 }
4635 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4636 {
4637 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4638 char extra[32];
4639 tANI_U8 len = 0;
4640
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004641 len = scnprintf(extra, sizeof(extra), "%s %d",
4642 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304643 len = VOS_MIN(priv_data.total_len, len + 1);
4644 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004645 {
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4647 "%s: failed to copy data to user buffer", __func__);
4648 ret = -EFAULT;
4649 goto exit;
4650 }
4651 }
4652 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4653 {
4654 tANI_U8 *value = command;
4655 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4656
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304657 ret = hdd_drv_cmd_validate(command, 25);
4658 if (ret)
4659 goto exit;
4660
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004661 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4662 value = value + 26;
4663 /* Convert the value from ascii to integer */
4664 ret = kstrtou8(value, 10, &minTime);
4665 if (ret < 0)
4666 {
4667 /* If the input value is greater than max value of datatype, then also
4668 kstrtou8 fails */
4669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4670 "%s: kstrtou8 failed range [%d - %d]", __func__,
4671 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4672 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4673 ret = -EINVAL;
4674 goto exit;
4675 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004676 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4677 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4678 {
4679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "scan min channel time value %d is out of range"
4681 " (Min: %d Max: %d)", minTime,
4682 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4683 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4684 ret = -EINVAL;
4685 goto exit;
4686 }
4687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4689 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4690 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4692 "%s: Received Command to change channel min time = %d", __func__, minTime);
4693
4694 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4695 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4696 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004697 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4698 {
4699 tANI_U8 *value = command;
4700 tANI_U8 channel = 0;
4701 tANI_U8 dwellTime = 0;
4702 tANI_U8 bufLen = 0;
4703 tANI_U8 *buf = NULL;
4704 tSirMacAddr targetApBssid;
4705 eHalStatus status = eHAL_STATUS_SUCCESS;
4706 struct ieee80211_channel chan;
4707 tANI_U8 finalLen = 0;
4708 tANI_U8 *finalBuf = NULL;
4709 tANI_U8 temp = 0;
4710 u64 cookie;
4711 hdd_station_ctx_t *pHddStaCtx = NULL;
4712 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4713
4714 /* if not associated, no need to send action frame */
4715 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4716 {
4717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4718 ret = -EINVAL;
4719 goto exit;
4720 }
4721
4722 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4723 &dwellTime, &buf, &bufLen);
4724 if (eHAL_STATUS_SUCCESS != status)
4725 {
4726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4727 "%s: Failed to parse send action frame data", __func__);
4728 ret = -EINVAL;
4729 goto exit;
4730 }
4731
4732 /* if the target bssid is different from currently associated AP,
4733 then no need to send action frame */
4734 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4735 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4736 {
4737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4738 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004739 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004740 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004741 goto exit;
4742 }
4743
4744 /* if the channel number is different from operating channel then
4745 no need to send action frame */
4746 if (channel != pHddStaCtx->conn_info.operationChannel)
4747 {
4748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4749 "%s: channel(%d) is different from operating channel(%d)",
4750 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4751 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004752 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004753 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004754 goto exit;
4755 }
4756 chan.center_freq = sme_ChnToFreq(channel);
4757
4758 finalLen = bufLen + 24;
4759 finalBuf = vos_mem_malloc(finalLen);
4760 if (NULL == finalBuf)
4761 {
4762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4763 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004764 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004765 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004766 goto exit;
4767 }
4768 vos_mem_zero(finalBuf, finalLen);
4769
4770 /* Fill subtype */
4771 temp = SIR_MAC_MGMT_ACTION << 4;
4772 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4773
4774 /* Fill type */
4775 temp = SIR_MAC_MGMT_FRAME;
4776 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4777
4778 /* Fill destination address (bssid of the AP) */
4779 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4780
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004781 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004782 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4783
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004784 /* Fill BSSID (AP mac address) */
4785 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004786
4787 /* Fill received buffer from 24th address */
4788 vos_mem_copy(finalBuf + 24, buf, bufLen);
4789
Jeff Johnson11c33152013-04-16 17:52:40 -07004790 /* done with the parsed buffer */
4791 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004792 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004793
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4795 params.chan = &chan;
4796 params.offchan = 0;
4797 params.wait = dwellTime;
4798 params.buf = finalBuf;
4799 params.len = finalLen;
4800 params.no_cck = 1;
4801 params.dont_wait_for_ack = 1;
4802 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4803#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304804 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4806 &(pAdapter->wdev),
4807#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004808 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004809#endif
4810 &chan, 0,
4811#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4812 NL80211_CHAN_HT20, 1,
4813#endif
4814 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004815 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304816#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004817 vos_mem_free(finalBuf);
4818 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004819 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4820 {
4821 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4822 char extra[32];
4823 tANI_U8 len = 0;
4824
4825 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004826 len = scnprintf(extra, sizeof(extra), "%s %d",
4827 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4829 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4830 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304831 len = VOS_MIN(priv_data.total_len, len + 1);
4832 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004833 {
4834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4835 "%s: failed to copy data to user buffer", __func__);
4836 ret = -EFAULT;
4837 goto exit;
4838 }
4839 }
4840 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4841 {
4842 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004843 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004844
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304845 ret = hdd_drv_cmd_validate(command, 18);
4846 if (ret)
4847 goto exit;
4848
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004849 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4850 value = value + 19;
4851 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004852 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004853 if (ret < 0)
4854 {
4855 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004856 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004858 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004859 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4860 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4861 ret = -EINVAL;
4862 goto exit;
4863 }
4864
4865 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4866 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4867 {
4868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4869 "lfr mode value %d is out of range"
4870 " (Min: %d Max: %d)", maxTime,
4871 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4872 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4873 ret = -EINVAL;
4874 goto exit;
4875 }
4876
4877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4878 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4879
4880 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4881 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4882 }
4883 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4884 {
4885 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4886 char extra[32];
4887 tANI_U8 len = 0;
4888
4889 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004890 len = scnprintf(extra, sizeof(extra), "%s %d",
4891 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304892 len = VOS_MIN(priv_data.total_len, len + 1);
4893 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004894 {
4895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4896 "%s: failed to copy data to user buffer", __func__);
4897 ret = -EFAULT;
4898 goto exit;
4899 }
4900 }
4901 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4902 {
4903 tANI_U8 *value = command;
4904 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4905
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304906 ret = hdd_drv_cmd_validate(command, 15);
4907 if (ret)
4908 goto exit;
4909
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004910 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4911 value = value + 16;
4912 /* Convert the value from ascii to integer */
4913 ret = kstrtou16(value, 10, &val);
4914 if (ret < 0)
4915 {
4916 /* If the input value is greater than max value of datatype, then also
4917 kstrtou16 fails */
4918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4919 "%s: kstrtou16 failed range [%d - %d]", __func__,
4920 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4921 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4922 ret = -EINVAL;
4923 goto exit;
4924 }
4925
4926 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4927 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4928 {
4929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4930 "scan home time value %d is out of range"
4931 " (Min: %d Max: %d)", val,
4932 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4933 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4934 ret = -EINVAL;
4935 goto exit;
4936 }
4937
4938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4939 "%s: Received Command to change scan home time = %d", __func__, val);
4940
4941 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4942 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4943 }
4944 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4945 {
4946 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4947 char extra[32];
4948 tANI_U8 len = 0;
4949
4950 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004951 len = scnprintf(extra, sizeof(extra), "%s %d",
4952 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304953 len = VOS_MIN(priv_data.total_len, len + 1);
4954 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004955 {
4956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4957 "%s: failed to copy data to user buffer", __func__);
4958 ret = -EFAULT;
4959 goto exit;
4960 }
4961 }
4962 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4963 {
4964 tANI_U8 *value = command;
4965 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4966
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304967 ret = hdd_drv_cmd_validate(command, 16);
4968 if (ret)
4969 goto exit;
4970
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004971 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4972 value = value + 17;
4973 /* Convert the value from ascii to integer */
4974 ret = kstrtou8(value, 10, &val);
4975 if (ret < 0)
4976 {
4977 /* If the input value is greater than max value of datatype, then also
4978 kstrtou8 fails */
4979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4980 "%s: kstrtou8 failed range [%d - %d]", __func__,
4981 CFG_ROAM_INTRA_BAND_MIN,
4982 CFG_ROAM_INTRA_BAND_MAX);
4983 ret = -EINVAL;
4984 goto exit;
4985 }
4986
4987 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4988 (val > CFG_ROAM_INTRA_BAND_MAX))
4989 {
4990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4991 "intra band mode value %d is out of range"
4992 " (Min: %d Max: %d)", val,
4993 CFG_ROAM_INTRA_BAND_MIN,
4994 CFG_ROAM_INTRA_BAND_MAX);
4995 ret = -EINVAL;
4996 goto exit;
4997 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4999 "%s: Received Command to change intra band = %d", __func__, val);
5000
5001 pHddCtx->cfg_ini->nRoamIntraBand = val;
5002 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5003 }
5004 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5005 {
5006 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5007 char extra[32];
5008 tANI_U8 len = 0;
5009
5010 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005011 len = scnprintf(extra, sizeof(extra), "%s %d",
5012 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305013 len = VOS_MIN(priv_data.total_len, len + 1);
5014 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005015 {
5016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5017 "%s: failed to copy data to user buffer", __func__);
5018 ret = -EFAULT;
5019 goto exit;
5020 }
5021 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005022 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5023 {
5024 tANI_U8 *value = command;
5025 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5026
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305027 ret = hdd_drv_cmd_validate(command, 14);
5028 if (ret)
5029 goto exit;
5030
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005031 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5032 value = value + 15;
5033 /* Convert the value from ascii to integer */
5034 ret = kstrtou8(value, 10, &nProbes);
5035 if (ret < 0)
5036 {
5037 /* If the input value is greater than max value of datatype, then also
5038 kstrtou8 fails */
5039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5040 "%s: kstrtou8 failed range [%d - %d]", __func__,
5041 CFG_ROAM_SCAN_N_PROBES_MIN,
5042 CFG_ROAM_SCAN_N_PROBES_MAX);
5043 ret = -EINVAL;
5044 goto exit;
5045 }
5046
5047 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5048 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5049 {
5050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5051 "NProbes value %d is out of range"
5052 " (Min: %d Max: %d)", nProbes,
5053 CFG_ROAM_SCAN_N_PROBES_MIN,
5054 CFG_ROAM_SCAN_N_PROBES_MAX);
5055 ret = -EINVAL;
5056 goto exit;
5057 }
5058
5059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5060 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5061
5062 pHddCtx->cfg_ini->nProbes = nProbes;
5063 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5064 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305065 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005066 {
5067 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5068 char extra[32];
5069 tANI_U8 len = 0;
5070
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005071 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305072 len = VOS_MIN(priv_data.total_len, len + 1);
5073 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5075 "%s: failed to copy data to user buffer", __func__);
5076 ret = -EFAULT;
5077 goto exit;
5078 }
5079 }
5080 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5081 {
5082 tANI_U8 *value = command;
5083 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5084
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305085 ret = hdd_drv_cmd_validate(command, 19);
5086 if (ret)
5087 goto exit;
5088
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005089 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5090 /* input value is in units of msec */
5091 value = value + 20;
5092 /* Convert the value from ascii to integer */
5093 ret = kstrtou16(value, 10, &homeAwayTime);
5094 if (ret < 0)
5095 {
5096 /* If the input value is greater than max value of datatype, then also
5097 kstrtou8 fails */
5098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5099 "%s: kstrtou8 failed range [%d - %d]", __func__,
5100 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5101 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5102 ret = -EINVAL;
5103 goto exit;
5104 }
5105
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005106 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5107 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5108 {
5109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5110 "homeAwayTime value %d is out of range"
5111 " (Min: %d Max: %d)", homeAwayTime,
5112 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5113 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5114 ret = -EINVAL;
5115 goto exit;
5116 }
5117
5118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5119 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005120 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5121 {
5122 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5123 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5124 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005125 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305126 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005127 {
5128 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5129 char extra[32];
5130 tANI_U8 len = 0;
5131
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005132 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305133 len = VOS_MIN(priv_data.total_len, len + 1);
5134 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5136 "%s: failed to copy data to user buffer", __func__);
5137 ret = -EFAULT;
5138 goto exit;
5139 }
5140 }
5141 else if (strncmp(command, "REASSOC", 7) == 0)
5142 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305143 ret = hdd_drv_cmd_validate(command, 7);
5144 if (ret)
5145 goto exit;
5146
5147 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305148 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005149 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005150 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005151 else if (strncmp(command, "SETWESMODE", 10) == 0)
5152 {
5153 tANI_U8 *value = command;
5154 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5155
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305156 ret = hdd_drv_cmd_validate(command, 10);
5157 if (ret)
5158 goto exit;
5159
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005160 /* Move pointer to ahead of SETWESMODE<delimiter> */
5161 value = value + 11;
5162 /* Convert the value from ascii to integer */
5163 ret = kstrtou8(value, 10, &wesMode);
5164 if (ret < 0)
5165 {
5166 /* If the input value is greater than max value of datatype, then also
5167 kstrtou8 fails */
5168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5169 "%s: kstrtou8 failed range [%d - %d]", __func__,
5170 CFG_ENABLE_WES_MODE_NAME_MIN,
5171 CFG_ENABLE_WES_MODE_NAME_MAX);
5172 ret = -EINVAL;
5173 goto exit;
5174 }
5175
5176 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5177 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5178 {
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5180 "WES Mode value %d is out of range"
5181 " (Min: %d Max: %d)", wesMode,
5182 CFG_ENABLE_WES_MODE_NAME_MIN,
5183 CFG_ENABLE_WES_MODE_NAME_MAX);
5184 ret = -EINVAL;
5185 goto exit;
5186 }
5187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5188 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5189
5190 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5191 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5192 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305193 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005194 {
5195 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5196 char extra[32];
5197 tANI_U8 len = 0;
5198
Arif Hussain826d9412013-11-12 16:44:54 -08005199 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305200 len = VOS_MIN(priv_data.total_len, len + 1);
5201 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5203 "%s: failed to copy data to user buffer", __func__);
5204 ret = -EFAULT;
5205 goto exit;
5206 }
5207 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005208#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005209#ifdef FEATURE_WLAN_LFR
5210 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5211 {
5212 tANI_U8 *value = command;
5213 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5214
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305215 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5216 hddLog(LOGE,
5217 FL("Roaming is always disabled in STA + MON concurrency"));
5218 ret = -EINVAL;
5219 goto exit;
5220 }
5221
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305222 ret = hdd_drv_cmd_validate(command, 11);
5223 if (ret)
5224 goto exit;
5225
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005226 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5227 value = value + 12;
5228 /* Convert the value from ascii to integer */
5229 ret = kstrtou8(value, 10, &lfrMode);
5230 if (ret < 0)
5231 {
5232 /* If the input value is greater than max value of datatype, then also
5233 kstrtou8 fails */
5234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5235 "%s: kstrtou8 failed range [%d - %d]", __func__,
5236 CFG_LFR_FEATURE_ENABLED_MIN,
5237 CFG_LFR_FEATURE_ENABLED_MAX);
5238 ret = -EINVAL;
5239 goto exit;
5240 }
5241
5242 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5243 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5244 {
5245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5246 "lfr mode value %d is out of range"
5247 " (Min: %d Max: %d)", lfrMode,
5248 CFG_LFR_FEATURE_ENABLED_MIN,
5249 CFG_LFR_FEATURE_ENABLED_MAX);
5250 ret = -EINVAL;
5251 goto exit;
5252 }
5253
5254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5255 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5256
5257 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5258 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5259 }
5260#endif
5261#ifdef WLAN_FEATURE_VOWIFI_11R
5262 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5263 {
5264 tANI_U8 *value = command;
5265 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5266
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305267 ret = hdd_drv_cmd_validate(command, 17);
5268 if (ret)
5269 goto exit;
5270
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005271 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5272 value = value + 18;
5273 /* Convert the value from ascii to integer */
5274 ret = kstrtou8(value, 10, &ft);
5275 if (ret < 0)
5276 {
5277 /* If the input value is greater than max value of datatype, then also
5278 kstrtou8 fails */
5279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5280 "%s: kstrtou8 failed range [%d - %d]", __func__,
5281 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5282 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5283 ret = -EINVAL;
5284 goto exit;
5285 }
5286
5287 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5288 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5289 {
5290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5291 "ft mode value %d is out of range"
5292 " (Min: %d Max: %d)", ft,
5293 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5294 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5295 ret = -EINVAL;
5296 goto exit;
5297 }
5298
5299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5300 "%s: Received Command to change ft mode = %d", __func__, ft);
5301
5302 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5303 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5304 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305305 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5306 {
5307 tANI_U8 *value = command;
5308 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305309
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305310 ret = hdd_drv_cmd_validate(command, 14);
5311 if (ret)
5312 goto exit;
5313
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305314 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5315 value = value + 15;
5316 /* Convert the value from ascii to integer */
5317 ret = kstrtou8(value, 10, &dfsScanMode);
5318 if (ret < 0)
5319 {
5320 /* If the input value is greater than max value of
5321 datatype, then also kstrtou8 fails
5322 */
5323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5324 "%s: kstrtou8 failed range [%d - %d]", __func__,
5325 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5326 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5327 ret = -EINVAL;
5328 goto exit;
5329 }
5330
5331 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5332 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5333 {
5334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5335 "dfsScanMode value %d is out of range"
5336 " (Min: %d Max: %d)", dfsScanMode,
5337 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5338 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5339 ret = -EINVAL;
5340 goto exit;
5341 }
5342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5343 "%s: Received Command to Set DFS Scan Mode = %d",
5344 __func__, dfsScanMode);
5345
5346 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5347 }
5348 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5349 {
5350 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5351 char extra[32];
5352 tANI_U8 len = 0;
5353
5354 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305355 len = VOS_MIN(priv_data.total_len, len + 1);
5356 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305357 {
5358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5359 "%s: failed to copy data to user buffer", __func__);
5360 ret = -EFAULT;
5361 goto exit;
5362 }
5363 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305364 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5365 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305366 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5367 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305368 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305369 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005370#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005371#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005372 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5373 {
5374 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005375 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005376
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305377 ret = hdd_drv_cmd_validate(command, 10);
5378 if (ret)
5379 goto exit;
5380
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005381 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005382 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005383 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005384 hdd_is_okc_mode_enabled(pHddCtx) &&
5385 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5386 {
5387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005388 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005389 " hence this operation is not permitted!", __func__);
5390 ret = -EPERM;
5391 goto exit;
5392 }
5393
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005394 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5395 value = value + 11;
5396 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005397 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005398 if (ret < 0)
5399 {
5400 /* If the input value is greater than max value of datatype, then also
5401 kstrtou8 fails */
5402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5403 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005404 CFG_ESE_FEATURE_ENABLED_MIN,
5405 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005406 ret = -EINVAL;
5407 goto exit;
5408 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005409 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5410 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005411 {
5412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005413 "Ese mode value %d is out of range"
5414 " (Min: %d Max: %d)", eseMode,
5415 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 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005421 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005422
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005423 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5424 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005425 }
5426#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005427 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5428 {
5429 tANI_U8 *value = command;
5430 tANI_BOOLEAN roamScanControl = 0;
5431
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305432 ret = hdd_drv_cmd_validate(command, 18);
5433 if (ret)
5434 goto exit;
5435
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005436 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5437 value = value + 19;
5438 /* Convert the value from ascii to integer */
5439 ret = kstrtou8(value, 10, &roamScanControl);
5440 if (ret < 0)
5441 {
5442 /* If the input value is greater than max value of datatype, then also
5443 kstrtou8 fails */
5444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5445 "%s: kstrtou8 failed ", __func__);
5446 ret = -EINVAL;
5447 goto exit;
5448 }
5449
5450 if (0 != roamScanControl)
5451 {
5452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5453 "roam scan control invalid value = %d",
5454 roamScanControl);
5455 ret = -EINVAL;
5456 goto exit;
5457 }
5458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5459 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5460
5461 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5462 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005463#ifdef FEATURE_WLAN_OKC
5464 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5465 {
5466 tANI_U8 *value = command;
5467 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5468
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305469 ret = hdd_drv_cmd_validate(command, 10);
5470 if (ret)
5471 goto exit;
5472
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005473 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005474 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005475 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005476 hdd_is_okc_mode_enabled(pHddCtx) &&
5477 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5478 {
5479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005480 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005481 " hence this operation is not permitted!", __func__);
5482 ret = -EPERM;
5483 goto exit;
5484 }
5485
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005486 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5487 value = value + 11;
5488 /* Convert the value from ascii to integer */
5489 ret = kstrtou8(value, 10, &okcMode);
5490 if (ret < 0)
5491 {
5492 /* If the input value is greater than max value of datatype, then also
5493 kstrtou8 fails */
5494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5495 "%s: kstrtou8 failed range [%d - %d]", __func__,
5496 CFG_OKC_FEATURE_ENABLED_MIN,
5497 CFG_OKC_FEATURE_ENABLED_MAX);
5498 ret = -EINVAL;
5499 goto exit;
5500 }
5501
5502 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5503 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5504 {
5505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5506 "Okc mode value %d is out of range"
5507 " (Min: %d Max: %d)", okcMode,
5508 CFG_OKC_FEATURE_ENABLED_MIN,
5509 CFG_OKC_FEATURE_ENABLED_MAX);
5510 ret = -EINVAL;
5511 goto exit;
5512 }
5513
5514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5515 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5516
5517 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5518 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005519#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305520 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005521 {
5522 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5523 char extra[32];
5524 tANI_U8 len = 0;
5525
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005526 len = scnprintf(extra, sizeof(extra), "%s %d",
5527 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305528 len = VOS_MIN(priv_data.total_len, len + 1);
5529 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5531 "%s: failed to copy data to user buffer", __func__);
5532 ret = -EFAULT;
5533 goto exit;
5534 }
5535 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305536#ifdef WLAN_FEATURE_PACKET_FILTERING
5537 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5538 {
5539 tANI_U8 filterType = 0;
5540 tANI_U8 *value = command;
5541
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305542 ret = hdd_drv_cmd_validate(command, 21);
5543 if (ret)
5544 goto exit;
5545
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305546 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5547 value = value + 22;
5548
5549 /* Convert the value from ascii to integer */
5550 ret = kstrtou8(value, 10, &filterType);
5551 if (ret < 0)
5552 {
5553 /* If the input value is greater than max value of datatype,
5554 * then also kstrtou8 fails
5555 */
5556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5557 "%s: kstrtou8 failed range ", __func__);
5558 ret = -EINVAL;
5559 goto exit;
5560 }
5561
5562 if (filterType != 0 && filterType != 1)
5563 {
5564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5565 "%s: Accepted Values are 0 and 1 ", __func__);
5566 ret = -EINVAL;
5567 goto exit;
5568 }
5569 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5570 pAdapter->sessionId);
5571 }
5572#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305573 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5574 {
Kiet Lamad161252014-07-22 11:23:32 -07005575 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305576 int ret;
5577
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305578 ret = hdd_drv_cmd_validate(command, 10);
5579 if (ret)
5580 goto exit;
5581
Kiet Lamad161252014-07-22 11:23:32 -07005582 dhcpPhase = command + 11;
5583 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305584 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005586 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305587
5588 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005589
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305590 ret = wlan_hdd_scan_abort(pAdapter);
5591 if (ret < 0)
5592 {
5593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5594 FL("failed to abort existing scan %d"), ret);
5595 }
5596
Kiet Lamad161252014-07-22 11:23:32 -07005597 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5598 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305599 }
Kiet Lamad161252014-07-22 11:23:32 -07005600 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305601 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005603 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305604
5605 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005606
5607 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5608 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305609 }
5610 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005611 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5612 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305613 hddLog(LOG1,
5614 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305615 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005616 }
5617 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5618 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305619 hddLog(LOG1,
5620 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305621 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005622 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305623 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5624 {
5625 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5626 char extra[32];
5627 tANI_U8 len = 0;
5628
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305629 memset(extra, 0, sizeof(extra));
5630 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305631 len = VOS_MIN(priv_data.total_len, len + 1);
5632 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5634 "%s: failed to copy data to user buffer", __func__);
5635 ret = -EFAULT;
5636 goto exit;
5637 }
5638 ret = len;
5639 }
5640 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5641 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305642 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305643 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305644 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5645 {
5646 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5647 char extra[32];
5648 tANI_U8 len = 0;
5649
5650 if (hdd_drv_cmd_validate(command, 15)) {
5651 hddLog(LOGE, FL("Invalid driver command"));
5652 return -EINVAL;
5653 }
5654
5655 memset(extra, 0, sizeof(extra));
5656 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5657 sizeof(extra), &len);
5658 len = VOS_MIN(priv_data.total_len, len + 1);
5659 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5660 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5661 ret = -EFAULT;
5662 goto exit;
5663 }
5664 ret = len;
5665 }
5666 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5667 {
5668 if (hdd_drv_cmd_validate(command, 15)) {
5669 hddLog(LOGE, FL("Invalid driver command"));
5670 return -EINVAL;
5671 }
5672 ret = hdd_btc_set_dwell_time(pAdapter, command);
5673 }
5674#ifdef WLAN_AP_STA_CONCURRENCY
5675 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5676 {
5677 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5678 char extra[32];
5679 tANI_U8 len = 0;
5680
5681 if (hdd_drv_cmd_validate(command, 16)) {
5682 hddLog(LOGE, FL("Invalid driver command"));
5683 return -EINVAL;
5684 }
5685
5686 memset(extra, 0, sizeof(extra));
5687 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5688 sizeof(extra), &len);
5689 len = VOS_MIN(priv_data.total_len, len + 1);
5690 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5691 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5692 ret = -EFAULT;
5693 goto exit;
5694 }
5695 ret = len;
5696 }
5697 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5698 {
5699 if (hdd_drv_cmd_validate(command, 16)) {
5700 hddLog(LOGE, FL("Invalid driver command"));
5701 return -EINVAL;
5702 }
5703 ret = hdd_conc_set_dwell_time(pAdapter, command);
5704 }
5705#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005706 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5707 {
5708 tANI_U8 filterType = 0;
5709 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305710
5711 ret = hdd_drv_cmd_validate(command, 8);
5712 if (ret)
5713 goto exit;
5714
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005715 value = command + 9;
5716
5717 /* Convert the value from ascii to integer */
5718 ret = kstrtou8(value, 10, &filterType);
5719 if (ret < 0)
5720 {
5721 /* If the input value is greater than max value of datatype,
5722 * then also kstrtou8 fails
5723 */
5724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5725 "%s: kstrtou8 failed range ", __func__);
5726 ret = -EINVAL;
5727 goto exit;
5728 }
5729 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5730 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5731 {
5732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5733 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5734 " 2-Sink ", __func__);
5735 ret = -EINVAL;
5736 goto exit;
5737 }
5738 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5739 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305740 pScanInfo = &pHddCtx->scan_info;
5741 if (filterType && pScanInfo != NULL &&
5742 pHddCtx->scan_info.mScanPending)
5743 {
5744 /*Miracast Session started. Abort Scan */
5745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5746 "%s, Aborting Scan For Miracast",__func__);
5747 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5748 eCSR_SCAN_ABORT_DEFAULT);
5749 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005750 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305751 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005752 }
Leo Chang614d2072013-08-22 14:59:44 -07005753 else if (strncmp(command, "SETMCRATE", 9) == 0)
5754 {
Leo Chang614d2072013-08-22 14:59:44 -07005755 tANI_U8 *value = command;
5756 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005757 tSirRateUpdateInd *rateUpdate;
5758 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005759
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305760 ret = hdd_drv_cmd_validate(command, 9);
5761 if (ret)
5762 goto exit;
5763
Leo Chang614d2072013-08-22 14:59:44 -07005764 /* Only valid for SAP mode */
5765 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5766 {
5767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5768 "%s: SAP mode is not running", __func__);
5769 ret = -EFAULT;
5770 goto exit;
5771 }
5772
5773 /* Move pointer to ahead of SETMCRATE<delimiter> */
5774 /* input value is in units of hundred kbps */
5775 value = value + 10;
5776 /* Convert the value from ascii to integer, decimal base */
5777 ret = kstrtouint(value, 10, &targetRate);
5778
Leo Chang1f98cbd2013-10-17 15:03:52 -07005779 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5780 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005781 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005782 hddLog(VOS_TRACE_LEVEL_ERROR,
5783 "%s: SETMCRATE indication alloc fail", __func__);
5784 ret = -EFAULT;
5785 goto exit;
5786 }
5787 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5788
5789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5790 "MC Target rate %d", targetRate);
5791 /* Ignore unicast */
5792 rateUpdate->ucastDataRate = -1;
5793 rateUpdate->mcastDataRate24GHz = targetRate;
5794 rateUpdate->mcastDataRate5GHz = targetRate;
5795 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5796 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5797 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5798 if (eHAL_STATUS_SUCCESS != status)
5799 {
5800 hddLog(VOS_TRACE_LEVEL_ERROR,
5801 "%s: SET_MC_RATE failed", __func__);
5802 vos_mem_free(rateUpdate);
5803 ret = -EFAULT;
5804 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005805 }
5806 }
jge35567202017-06-21 16:39:38 +08005807 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5808 {
5809 int status;
5810 int txPower;
5811 eHalStatus smeStatus;
5812 tANI_U8 *value = command;
5813 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5814 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5815
5816 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5817 if (status)
5818 {
5819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5820 "Invalid MAXTXPOWER command ");
5821 ret = -EINVAL;
5822 goto exit;
5823 }
5824
5825 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5826 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5827 txPower, MAC_ADDR_ARRAY(selfMac),
5828 MAC_ADDR_ARRAY(bssid));
5829 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5830 bssid, selfMac, txPower) ;
5831 if( smeStatus != eHAL_STATUS_SUCCESS )
5832 {
5833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5834 __func__);
5835 ret = -EINVAL;
5836 goto exit;
5837 }
5838
5839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5840 __func__);
5841 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305842#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005843 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305844 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005845 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305846 }
5847#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305848#ifdef WLAN_FEATURE_RMC
5849 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5850 (WLAN_HDD_IBSS == pAdapter->device_mode))
5851 {
5852 int i = 0;
5853 tANI_U8 *ibss_ie;
5854 tANI_U32 command_len;
5855 tANI_U8 *value = command;
5856 tHalHandle hHal = pHddCtx->hHal;
5857 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5858 tANI_U32 ibss_ie_length;
5859 tANI_U32 len, present;
5860 tANI_U8 *addIE;
5861 tANI_U8 *addIEData;
5862
5863 hddLog(LOG1,
5864 FL(" received command %s"),((char *) value));
5865 /* validate argument of command */
5866 if (strlen(value) <= 21)
5867 {
5868 hddLog(LOGE,
5869 FL("No arguements in command length %zu"), strlen(value));
5870 ret = -EFAULT;
5871 goto exit;
5872 }
5873
5874 /* moving to arguments of commands */
5875 value = value + 21;
5876 command_len = strlen(value);
5877
5878 /* oui_data can't be less than 3 bytes */
5879 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5880 {
5881 hddLog(LOGE,
5882 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5883 command_len);
5884 ret = -EFAULT;
5885 goto exit;
5886 }
5887 ibss_ie = vos_mem_malloc(command_len);
5888 if (!ibss_ie) {
5889 hddLog(LOGE,
5890 FL("Could not allocate memory for command length %d"),
5891 command_len);
5892 ret = -ENOMEM;
5893 goto exit;
5894 }
5895 vos_mem_zero(ibss_ie, command_len);
5896
5897 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5898 command_len);
5899 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5900 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5901 value, ibss_ie_length);
5902 ret = -EFAULT;
5903 vos_mem_free(ibss_ie);
5904 goto exit;
5905 }
5906
5907 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5908 while (i < ibss_ie_length)
5909 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5910
5911 /* Populate Vendor IE in Beacon */
5912 if ((ccmCfgGetInt(hHal,
5913 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5914 &present)) != eHAL_STATUS_SUCCESS)
5915 {
5916 hddLog(LOGE,
5917 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5918 ret = -EFAULT;
5919 vos_mem_free(ibss_ie);
5920 goto exit;
5921 }
5922
5923 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5924 if (!addIE) {
5925 hddLog(LOGE,
5926 FL("Could not allocate memory for command length %d"),
5927 command_len);
5928 vos_mem_free(ibss_ie);
5929 ret = -ENOMEM;
5930 goto exit;
5931 }
5932 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5933
5934 if (present)
5935 {
5936 if ((wlan_cfgGetStrLen(pMac,
5937 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5938 {
5939 hddLog(LOGE,
5940 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5941 ret = -EFAULT;
5942 vos_mem_free(ibss_ie);
5943 vos_mem_free(addIE);
5944 goto exit;
5945 }
5946
5947 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5948 ((len + ibss_ie_length) <=
5949 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5950 {
5951 if ((ccmCfgGetStr(hHal,
5952 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5953 != eHAL_STATUS_SUCCESS)
5954 {
5955 hddLog(LOGE,
5956 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5957 ret = -EFAULT;
5958 vos_mem_free(ibss_ie);
5959 vos_mem_free(addIE);
5960 goto exit;
5961 }
5962 else
5963 {
5964 /* Curruntly only WPA IE is added before Vendor IE
5965 * so we can blindly place the Vendor IE after WPA
5966 * IE. If no WPA IE found replace all with Vendor IE.
5967 */
5968 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5969 }
5970 }
5971 else
5972 {
5973 hddLog(LOGE,
5974 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5975 len, ibss_ie_length);
5976 ret = -EFAULT;
5977 vos_mem_free(addIE);
5978 vos_mem_free(ibss_ie);
5979 goto exit;
5980 }
5981 }
5982 else {
5983 len = 0;
5984 }
5985
5986 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5987 len += ibss_ie_length;
5988
5989 if (ccmCfgSetStr(hHal,
5990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5991 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5992 {
5993 hddLog(LOGE,
5994 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5995 ret = -EFAULT;
5996 vos_mem_free(ibss_ie);
5997 vos_mem_free(addIE);
5998 goto exit;
5999 }
6000 vos_mem_free(addIE);
6001 if (ccmCfgSetInt(hHal,
6002 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6003 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6004 {
6005 hddLog(LOGE,
6006 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6007 ret = -EFAULT;
6008 vos_mem_free(ibss_ie);
6009 goto exit;
6010 }
6011
6012 /* Populate Vendor IE in probe resp */
6013 if ((ccmCfgGetInt(hHal,
6014 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6015 &present)) != eHAL_STATUS_SUCCESS)
6016 {
6017 hddLog(LOGE,
6018 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6019 ret = -EFAULT;
6020 vos_mem_free(ibss_ie);
6021 goto exit;
6022 }
6023
6024 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6025 if (!addIEData) {
6026 hddLog(LOGE,
6027 FL("Could not allocate memory for command length %d"),
6028 command_len);
6029 vos_mem_free(ibss_ie);
6030 ret = -ENOMEM;
6031 goto exit;
6032 }
6033 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6034
6035 if (present) {
6036 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6037 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6038 hddLog(LOGE,
6039 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6040 ret = -EFAULT;
6041 vos_mem_free(ibss_ie);
6042 vos_mem_free(addIEData);
6043 goto exit;
6044 }
6045 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6046 (ibss_ie_length + len) <=
6047 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6048
6049 if ((ccmCfgGetStr(hHal,
6050 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6051 != eHAL_STATUS_SUCCESS) {
6052 hddLog(LOGE,
6053 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6054 ret = -EFAULT;
6055 vos_mem_free(ibss_ie);
6056 vos_mem_free(addIEData);
6057 goto exit;
6058 }
6059 else {
6060 /* Curruntly only WPA IE is added before Vendor IE
6061 * so we can blindly place the Vendor IE after WPA
6062 * IE. If no WPA IE found replace all with Vendor IE.
6063 */
6064 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6065 }
6066 }
6067 else
6068 {
6069 hddLog(LOGE,
6070 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6071 len, ibss_ie_length);
6072 ret = -EFAULT;
6073 vos_mem_free(addIEData);
6074 vos_mem_free(ibss_ie);
6075 goto exit;
6076 }
6077 } /* probe rsp ADD IE present */
6078 else {
6079 /* probe rsp add IE is not present */
6080 len = 0;
6081 }
6082
6083 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6084 len += ibss_ie_length;
6085
6086 vos_mem_free(ibss_ie);
6087
6088 if (ccmCfgSetStr(hHal,
6089 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6090 (tANI_U8*)(addIEData),
6091 len, NULL,
6092 eANI_BOOLEAN_FALSE)
6093 == eHAL_STATUS_FAILURE) {
6094 hddLog(LOGE,
6095 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6096 ret = -EFAULT;
6097 vos_mem_free(addIEData);
6098 goto exit;
6099 }
6100 vos_mem_free(addIEData);
6101 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6102 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6103 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6104 {
6105 hddLog(LOGE,
6106 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6107 ret = -EFAULT;
6108 goto exit;
6109 }
6110 }
6111 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6112 {
6113 tANI_U8 *value = command;
6114 tANI_U8 ucRmcEnable = 0;
6115 int status;
6116
6117 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6118 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6119 {
6120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6121 "Received SETRMCENABLE command in invalid mode %d "
6122 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6123 pAdapter->device_mode);
6124 ret = -EINVAL;
6125 goto exit;
6126 }
6127
6128 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6129 if (status)
6130 {
6131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6132 "Invalid SETRMCENABLE command ");
6133 ret = -EINVAL;
6134 goto exit;
6135 }
6136
6137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6138 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6139
6140 if (TRUE == ucRmcEnable)
6141 {
6142 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6143 pAdapter->sessionId );
6144 }
6145 else if(FALSE == ucRmcEnable)
6146 {
6147 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6148 pAdapter->sessionId );
6149 }
6150 else
6151 {
6152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6153 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6154 ret = -EINVAL;
6155 goto exit;
6156 }
6157
6158 if (VOS_STATUS_SUCCESS != status)
6159 {
6160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6161 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6162 status);
6163 ret = -EINVAL;
6164 goto exit;
6165 }
6166 }
6167 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6168 {
6169 tANI_U8 *value = command;
6170 tANI_U32 uActionPeriod = 0;
6171 int status;
6172
6173 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6174 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6175 {
6176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6177 "Received SETRMC command in invalid mode %d "
6178 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6179 pAdapter->device_mode);
6180 ret = -EINVAL;
6181 goto exit;
6182 }
6183
6184 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6185 if (status)
6186 {
6187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6188 "Invalid SETRMCACTIONPERIOD command ");
6189 ret = -EINVAL;
6190 goto exit;
6191 }
6192
6193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6194 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6195
6196 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6197 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6198 {
6199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6200 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6201 ret = -EINVAL;
6202 goto exit;
6203 }
6204
6205 }
6206 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6207 {
6208 /* Peer Info All Command */
6209 int status = eHAL_STATUS_SUCCESS;
6210 hdd_station_ctx_t *pHddStaCtx = NULL;
6211 char *extra = NULL;
6212 int idx = 0, length = 0;
6213 v_MACADDR_t *macAddr;
6214 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6215
6216 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6217 {
6218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6219 }
6220 else
6221 {
6222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6223 "%s: pAdapter is not valid for this device mode",
6224 __func__);
6225 ret = -EINVAL;
6226 goto exit;
6227 }
6228
6229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6230 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6231
6232
6233 /* Handle the command */
6234 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6235 if (VOS_STATUS_SUCCESS == status)
6236 {
6237 /* The variable extra needed to be allocated on the heap since
6238 * amount of memory required to copy the data for 32 devices
6239 * exceeds the size of 1024 bytes of default stack size. On
6240 * 64 bit devices, the default max stack size of 2048 bytes
6241 */
6242 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6243
6244 if (NULL == extra)
6245 {
6246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 "%s:kmalloc failed", __func__);
6248 ret = -EINVAL;
6249 goto exit;
6250 }
6251
6252 /* Copy number of stations */
6253 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6254 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6255 numOfBytestoPrint = length;
6256 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6257 {
6258 macAddr =
6259 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6260 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6261 if (NULL != macAddr)
6262 {
6263 txRateMbps =
6264 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6265
6266 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6267 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6268 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6269 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6270 (int)txRateMbps,
6271 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6272 }
6273 else
6274 {
6275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6276 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6277 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6278 }
6279
6280 /*
6281 * VOS_TRACE() macro has limitation of 512 bytes for the print
6282 * buffer. Hence printing the data in two chunks. The first chunk
6283 * will have the data for 16 devices and the second chunk will
6284 * have the rest.
6285 */
6286 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6287 {
6288 numOfBytestoPrint = length;
6289 }
6290 }
6291
6292 /*
6293 * Copy the data back into buffer, if the data to copy is
6294 * morethan 512 bytes than we will split the data and do
6295 * it in two shots
6296 */
6297 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6298 {
6299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6300 "%s: Copy into user data buffer failed ", __func__);
6301 ret = -EFAULT;
6302 kfree(extra);
6303 goto exit;
6304 }
6305 priv_data.buf[numOfBytestoPrint] = '\0';
6306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6307 "%s", priv_data.buf);
6308
6309 if (length > numOfBytestoPrint)
6310 {
6311 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6312 extra + numOfBytestoPrint,
6313 length - numOfBytestoPrint + 1))
6314 {
6315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6316 "%s: Copy into user data buffer failed ", __func__);
6317 ret = -EFAULT;
6318 kfree(extra);
6319 goto exit;
6320 }
6321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6322 "%s", &priv_data.buf[numOfBytestoPrint]);
6323 }
6324
6325 /* Free temporary buffer */
6326 kfree(extra);
6327 }
6328
6329 else
6330 {
6331 /* Command failed, log error */
6332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6333 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6334 __func__, status);
6335 ret = -EINVAL;
6336 goto exit;
6337 }
6338 ret = 0;
6339 }
6340 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6341 {
6342 /* Peer Info <Peer Addr> command */
6343 tANI_U8 *value = command;
6344 VOS_STATUS status;
6345 hdd_station_ctx_t *pHddStaCtx = NULL;
6346 char extra[128] = { 0 };
6347 v_U32_t length = 0;
6348 v_U8_t staIdx = 0;
6349 v_U32_t txRateMbps = 0;
6350 v_MACADDR_t peerMacAddr;
6351
6352 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6353 {
6354 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6355 }
6356 else
6357 {
6358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6359 "%s: pAdapter is not valid for this device mode",
6360 __func__);
6361 ret = -EINVAL;
6362 goto exit;
6363 }
6364
6365 /* if there are no peers, no need to continue with the command */
6366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6367 "%s: Received GETIBSSPEERINFO Command", __func__);
6368
6369 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6370 {
6371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6372 "%s:No IBSS Peers coalesced", __func__);
6373 ret = -EINVAL;
6374 goto exit;
6375 }
6376
6377 /* Parse the incoming command buffer */
6378 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6379 if (VOS_STATUS_SUCCESS != status)
6380 {
6381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6382 "%s: Invalid GETIBSSPEERINFO command", __func__);
6383 ret = -EINVAL;
6384 goto exit;
6385 }
6386
6387 /* Get station index for the peer mac address */
6388 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6389
6390 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6391 {
6392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6393 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6394 ret = -EINVAL;
6395 goto exit;
6396 }
6397
6398 /* Handle the command */
6399 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6400 if (VOS_STATUS_SUCCESS == status)
6401 {
6402 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6403 txRateMbps = (txRate * 500 * 1000)/1000000;
6404
6405 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6406 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6407
6408 /* Copy the data back into buffer */
6409 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6410 {
6411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6412 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6413 __func__);
6414 ret = -EFAULT;
6415 goto exit;
6416 }
6417 }
6418 else
6419 {
6420 /* Command failed, log error */
6421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6422 "%s: GETIBSSPEERINFO command failed with status code %d",
6423 __func__, status);
6424 ret = -EINVAL;
6425 goto exit;
6426 }
6427
6428 /* Success ! */
6429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6430 "%s", priv_data.buf);
6431 ret = 0;
6432 }
6433 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6434 {
6435 tANI_U8 *value = command;
6436 tANI_U32 uRate = 0;
6437 tTxrateinfoflags txFlags = 0;
6438 tSirRateUpdateInd *rateUpdateParams;
6439 int status;
6440
6441 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6442 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6443 {
6444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6445 "Received SETRMCTXRATE command in invalid mode %d "
6446 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6447 pAdapter->device_mode);
6448 ret = -EINVAL;
6449 goto exit;
6450 }
6451
6452 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6453 if (status)
6454 {
6455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6456 "Invalid SETRMCTXRATE command ");
6457 ret = -EINVAL;
6458 goto exit;
6459 }
6460
6461 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6462 if (NULL == rateUpdateParams)
6463 {
6464 ret = -EINVAL;
6465 goto exit;
6466 }
6467
6468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6469 "%s: uRate %d ", __func__, uRate);
6470
6471 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6472
6473 /* -1 implies ignore this param */
6474 rateUpdateParams->ucastDataRate = -1;
6475
6476 /*
6477 * Fill the user specifieed RMC rate param
6478 * and the derived tx flags.
6479 */
6480 rateUpdateParams->rmcDataRate = uRate;
6481 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6482
6483 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6484 }
6485 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6486 {
6487 char *value;
6488 tANI_U8 tx_fail_count = 0;
6489 tANI_U16 pid = 0;
6490
6491 value = command;
6492
6493 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6494
6495 if (0 != ret)
6496 {
6497 hddLog(VOS_TRACE_LEVEL_INFO,
6498 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6499 __func__);
6500 goto exit;
6501 }
6502
6503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6504 __func__, tx_fail_count, pid);
6505
6506 if (0 == tx_fail_count)
6507 {
6508 // Disable TX Fail Indication
6509 if (eHAL_STATUS_SUCCESS ==
6510 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6511 tx_fail_count,
6512 NULL))
6513 {
6514 cesium_pid = 0;
6515 }
6516 else
6517 {
6518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6519 "%s: failed to disable TX Fail Event ", __func__);
6520 ret = -EINVAL;
6521 }
6522 }
6523 else
6524 {
6525 if (eHAL_STATUS_SUCCESS ==
6526 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6527 tx_fail_count,
6528 (void*)hdd_tx_fail_ind_callback))
6529 {
6530 cesium_pid = pid;
6531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6532 "%s: Registered Cesium pid %u", __func__,
6533 cesium_pid);
6534 }
6535 else
6536 {
6537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6538 "%s: Failed to enable TX Fail Monitoring", __func__);
6539 ret = -EINVAL;
6540 }
6541 }
6542 }
6543
6544#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006545#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006546 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6547 {
6548 tANI_U8 *value = command;
6549 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6550 tANI_U8 numChannels = 0;
6551 eHalStatus status = eHAL_STATUS_SUCCESS;
6552
6553 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6554 if (eHAL_STATUS_SUCCESS != status)
6555 {
6556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6557 "%s: Failed to parse channel list information", __func__);
6558 ret = -EINVAL;
6559 goto exit;
6560 }
6561
6562 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6563 {
6564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6565 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6566 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6567 ret = -EINVAL;
6568 goto exit;
6569 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006570 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006571 ChannelList,
6572 numChannels);
6573 if (eHAL_STATUS_SUCCESS != status)
6574 {
6575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6576 "%s: Failed to update channel list information", __func__);
6577 ret = -EINVAL;
6578 goto exit;
6579 }
6580 }
6581 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6582 {
6583 tANI_U8 *value = command;
6584 char extra[128] = {0};
6585 int len = 0;
6586 tANI_U8 tid = 0;
6587 hdd_station_ctx_t *pHddStaCtx = NULL;
6588 tAniTrafStrmMetrics tsmMetrics;
6589 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6590
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306591 ret = hdd_drv_cmd_validate(command, 11);
6592 if (ret)
6593 goto exit;
6594
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006595 /* if not associated, return error */
6596 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6597 {
6598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6599 ret = -EINVAL;
6600 goto exit;
6601 }
6602
6603 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6604 value = value + 12;
6605 /* Convert the value from ascii to integer */
6606 ret = kstrtou8(value, 10, &tid);
6607 if (ret < 0)
6608 {
6609 /* If the input value is greater than max value of datatype, then also
6610 kstrtou8 fails */
6611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6612 "%s: kstrtou8 failed range [%d - %d]", __func__,
6613 TID_MIN_VALUE,
6614 TID_MAX_VALUE);
6615 ret = -EINVAL;
6616 goto exit;
6617 }
6618
6619 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6620 {
6621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6622 "tid value %d is out of range"
6623 " (Min: %d Max: %d)", tid,
6624 TID_MIN_VALUE,
6625 TID_MAX_VALUE);
6626 ret = -EINVAL;
6627 goto exit;
6628 }
6629
6630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6631 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6632
6633 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6634 {
6635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6636 "%s: failed to get tsm stats", __func__);
6637 ret = -EFAULT;
6638 goto exit;
6639 }
6640
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6642 "UplinkPktQueueDly(%d)\n"
6643 "UplinkPktQueueDlyHist[0](%d)\n"
6644 "UplinkPktQueueDlyHist[1](%d)\n"
6645 "UplinkPktQueueDlyHist[2](%d)\n"
6646 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306647 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006648 "UplinkPktLoss(%d)\n"
6649 "UplinkPktCount(%d)\n"
6650 "RoamingCount(%d)\n"
6651 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6652 tsmMetrics.UplinkPktQueueDlyHist[0],
6653 tsmMetrics.UplinkPktQueueDlyHist[1],
6654 tsmMetrics.UplinkPktQueueDlyHist[2],
6655 tsmMetrics.UplinkPktQueueDlyHist[3],
6656 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6657 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6658
6659 /* Output TSM stats is of the format
6660 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6661 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006662 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006663 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6664 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6665 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6666 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6667 tsmMetrics.RoamingDly);
6668
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306669 len = VOS_MIN(priv_data.total_len, len + 1);
6670 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6672 "%s: failed to copy data to user buffer", __func__);
6673 ret = -EFAULT;
6674 goto exit;
6675 }
6676 }
6677 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6678 {
6679 tANI_U8 *value = command;
6680 tANI_U8 *cckmIe = NULL;
6681 tANI_U8 cckmIeLen = 0;
6682 eHalStatus status = eHAL_STATUS_SUCCESS;
6683
6684 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6685 if (eHAL_STATUS_SUCCESS != status)
6686 {
6687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6688 "%s: Failed to parse cckm ie data", __func__);
6689 ret = -EINVAL;
6690 goto exit;
6691 }
6692
6693 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6694 {
6695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6696 "%s: CCKM Ie input length is more than max[%d]", __func__,
6697 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006698 vos_mem_free(cckmIe);
6699 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006700 ret = -EINVAL;
6701 goto exit;
6702 }
6703 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006704 vos_mem_free(cckmIe);
6705 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006706 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006707 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6708 {
6709 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006710 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006711 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006712
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006713 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006714 if (eHAL_STATUS_SUCCESS != status)
6715 {
6716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006717 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006718 ret = -EINVAL;
6719 goto exit;
6720 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006721 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6722 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6723 hdd_indicateEseBcnReportNoResults (pAdapter,
6724 eseBcnReq.bcnReq[0].measurementToken,
6725 0x02, //BIT(1) set for measurement done
6726 0); // no BSS
6727 goto exit;
6728 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006729
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006730 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6731 if (eHAL_STATUS_SUCCESS != status)
6732 {
6733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6734 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6735 ret = -EINVAL;
6736 goto exit;
6737 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006738 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006739#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306740 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6741 {
6742 eHalStatus status;
6743 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306744 void *cookie;
6745 struct hdd_request *request;
6746 struct bcn_miss_rate_priv *priv;
6747 static const struct hdd_request_params params = {
6748 .priv_size = sizeof(*priv),
6749 .timeout_ms = WLAN_WAIT_TIME_STATS,
6750 };
c_hpothu92367912014-05-01 15:18:17 +05306751
6752 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6753
6754 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6755 {
6756 hddLog(VOS_TRACE_LEVEL_WARN,
6757 FL("GETBCNMISSRATE: STA is not in connected state"));
6758 ret = -1;
6759 goto exit;
6760 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306761 request = hdd_request_alloc(&params);
6762 if (!request) {
6763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6764 ret = -ENOMEM;
6765 goto exit;
6766 }
6767 cookie = hdd_request_cookie(request);
6768 priv = hdd_request_priv(request);
6769 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306770
6771 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6772 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306773 (void *)get_bcn_miss_rate_cb,
6774 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306775 if( eHAL_STATUS_SUCCESS != status)
6776 {
6777 hddLog(VOS_TRACE_LEVEL_INFO,
6778 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6779 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306780 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306781 }
6782
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306783 ret = hdd_request_wait_for_response(request);
6784 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306785 {
6786 hddLog(VOS_TRACE_LEVEL_ERROR,
6787 FL("failed to wait on bcnMissRateComp %d"), ret);
6788
c_hpothu92367912014-05-01 15:18:17 +05306789 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306790 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306791 }
6792
6793 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306794 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306795
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306796 if (priv->bcn_miss_rate == -1) {
6797 ret = -EFAULT;
6798 goto free_bcn_miss_rate_req;
6799 }
6800
6801 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6802 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306803 if (copy_to_user(priv_data.buf, &buf, len + 1))
6804 {
6805 hddLog(VOS_TRACE_LEVEL_ERROR,
6806 "%s: failed to copy data to user buffer", __func__);
6807 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306808 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306809 }
6810 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306811
6812free_bcn_miss_rate_req:
6813 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306814 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306815#ifdef FEATURE_WLAN_TDLS
6816 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6817 tANI_U8 *value = command;
6818 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306819
6820 ret = hdd_drv_cmd_validate(command, 26);
6821 if (ret)
6822 goto exit;
6823
Atul Mittal87ec2422014-09-24 13:12:50 +05306824 /* Move pointer to ahead of TDLSOFFCH*/
6825 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306826 if (!(sscanf(value, "%d", &set_value))) {
6827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6828 FL("No input identified"));
6829 ret = -EINVAL;
6830 goto exit;
6831 }
6832
Atul Mittal87ec2422014-09-24 13:12:50 +05306833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6834 "%s: Tdls offchannel offset:%d",
6835 __func__, set_value);
6836 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6837 if (ret < 0)
6838 {
6839 ret = -EINVAL;
6840 goto exit;
6841 }
6842
6843 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6844 tANI_U8 *value = command;
6845 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306846
6847 ret = hdd_drv_cmd_validate(command, 18);
6848 if (ret)
6849 goto exit;
6850
Atul Mittal87ec2422014-09-24 13:12:50 +05306851 /* Move pointer to ahead of tdlsoffchnmode*/
6852 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306853 ret = sscanf(value, "%d", &set_value);
6854 if (ret != 1) {
6855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6856 FL("No input identified"));
6857 ret = -EINVAL;
6858 goto exit;
6859 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6861 "%s: Tdls offchannel mode:%d",
6862 __func__, set_value);
6863 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6864 if (ret < 0)
6865 {
6866 ret = -EINVAL;
6867 goto exit;
6868 }
6869 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6870 tANI_U8 *value = command;
6871 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306872
6873 ret = hdd_drv_cmd_validate(command, 14);
6874 if (ret)
6875 goto exit;
6876
Atul Mittal87ec2422014-09-24 13:12:50 +05306877 /* Move pointer to ahead of TDLSOFFCH*/
6878 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306879 ret = sscanf(value, "%d", &set_value);
6880 if (ret != 1) {
6881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6882 "Wrong value is given for hdd_set_tdls_offchannel");
6883 ret = -EINVAL;
6884 goto exit;
6885 }
6886
Atul Mittal87ec2422014-09-24 13:12:50 +05306887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6888 "%s: Tdls offchannel num: %d",
6889 __func__, set_value);
6890 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6891 if (ret < 0)
6892 {
6893 ret = -EINVAL;
6894 goto exit;
6895 }
6896 }
6897#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306898 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6899 {
6900 eHalStatus status;
6901 char *buf = NULL;
6902 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306903 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6904 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306905 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306906 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306907 void *cookie;
6908 struct hdd_request *request;
6909 struct fw_stats_priv *priv;
6910 static const struct hdd_request_params params = {
6911 .priv_size = sizeof(*priv),
6912 .timeout_ms = WLAN_WAIT_TIME_STATS,
6913 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306914
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306915 ret = hdd_drv_cmd_validate(command, 10);
6916 if (ret)
6917 goto exit;
6918
6919 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306920 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6921 if (!IS_FEATURE_FW_STATS_ENABLE)
6922 {
6923 hddLog(VOS_TRACE_LEVEL_INFO,
6924 FL("Get Firmware stats feature not supported"));
6925 ret = -EINVAL;
6926 goto exit;
6927 }
6928
6929 if (FW_STATS_MAX <= stats || 0 >= stats)
6930 {
6931 hddLog(VOS_TRACE_LEVEL_INFO,
6932 FL(" stats %d not supported"),stats);
6933 ret = -EINVAL;
6934 goto exit;
6935 }
6936
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306937 request = hdd_request_alloc(&params);
6938 if (!request) {
6939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6940 ret = -ENOMEM;
6941 goto exit;
6942 }
6943 cookie = hdd_request_cookie(request);
6944
Satyanarayana Dash72806012014-12-02 14:30:08 +05306945 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306946 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306947 if (eHAL_STATUS_SUCCESS != status)
6948 {
6949 hddLog(VOS_TRACE_LEVEL_ERROR,
6950 FL(" fail to post WDA cmd status = %d"), status);
6951 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306952 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306953 goto exit;
6954 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306955 ret = hdd_request_wait_for_response(request);
6956 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306957 {
6958 hddLog(VOS_TRACE_LEVEL_ERROR,
6959 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306960 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306961 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306962 goto exit;
6963 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306964
6965 priv = hdd_request_priv(request);
6966 fw_stats_result = priv->fw_stats;
6967 fwStatsRsp->type = 0;
6968 if (NULL != fw_stats_result)
6969 {
6970 switch (fw_stats_result->type )
6971 {
6972 case FW_UBSP_STATS:
6973 {
6974 tSirUbspFwStats *stats =
6975 &fwStatsRsp->fwStatsData.ubspStats;
6976 memcpy(fwStatsRsp, fw_stats_result,
6977 sizeof(tSirFwStatsResult));
6978 hddLog(VOS_TRACE_LEVEL_INFO,
6979 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6980 stats->ubsp_enter_cnt,
6981 stats->ubsp_jump_ddr_cnt);
6982 }
6983 break;
6984
6985 default:
6986 {
6987 hddLog(VOS_TRACE_LEVEL_ERROR,
6988 FL("No handling for stats type %d"),
6989 fw_stats_result->type);
6990 }
6991 }
6992 }
6993 hdd_request_put(request);
6994
Satyanarayana Dash72806012014-12-02 14:30:08 +05306995 if (fwStatsRsp->type)
6996 {
6997 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6998 if (!buf)
6999 {
7000 hddLog(VOS_TRACE_LEVEL_ERROR,
7001 FL(" failed to allocate memory"));
7002 ret = -ENOMEM;
7003 goto exit;
7004 }
7005 switch( fwStatsRsp->type )
7006 {
7007 case FW_UBSP_STATS:
7008 {
7009 len = snprintf(buf, FW_STATE_RSP_LEN,
7010 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307011 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7012 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307013 }
7014 break;
7015 default:
7016 {
7017 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7018 ret = -EFAULT;
7019 kfree(buf);
7020 goto exit;
7021 }
7022 }
7023 if (copy_to_user(priv_data.buf, buf, len + 1))
7024 {
7025 hddLog(VOS_TRACE_LEVEL_ERROR,
7026 FL(" failed to copy data to user buffer"));
7027 ret = -EFAULT;
7028 kfree(buf);
7029 goto exit;
7030 }
7031 ret = len;
7032 kfree(buf);
7033 }
7034 else
7035 {
7036 hddLog(VOS_TRACE_LEVEL_ERROR,
7037 FL("failed to fetch the stats"));
7038 ret = -EFAULT;
7039 goto exit;
7040 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307041 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307042 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7043 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307044 ret = hdd_drv_cmd_validate(command, 15);
7045 if (ret)
7046 goto exit;
7047
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307048 /*
7049 * this command wld be called by user-space when it detects WLAN
7050 * ON after airplane mode is set. When APM is set, WLAN turns off.
7051 * But it can be turned back on. Otherwise; when APM is turned back
7052 * off, WLAN wld turn back on. So at that point the command is
7053 * expected to come down. 0 means disable, 1 means enable. The
7054 * constraint is removed when parameter 1 is set or different
7055 * country code is set
7056 */
7057 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7058 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307059 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7060 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307061 ret = hdd_drv_cmd_validate(command, 16);
7062 if (ret)
7063 goto exit;
7064
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307065 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7066 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307067 /*
7068 * command should be a string having format
7069 * SET_DISABLE_CHANNEL_LIST <num of channels>
7070 * <channels separated by spaces>
7071 */
7072 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7073 tANI_U8 *ptr = command;
7074 ret = hdd_drv_cmd_validate(command, 24);
7075 if (ret)
7076 goto exit;
7077
7078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7079 " Received Command to disable Channels %s",
7080 __func__);
7081 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7082 if (ret)
7083 goto exit;
7084 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307085 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307086 char extra[512] = {0};
7087 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307088
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307090 " Received Command to get disable Channels list %s",
7091 __func__);
7092
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307093 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7094 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7095 if (copied_length == 0) {
7096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307097 FL("disable channel list are not yet programed"));
7098 ret = -EINVAL;
7099 goto exit;
7100 }
7101
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307102 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7104 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307105 ret = -EFAULT;
7106 goto exit;
7107 }
7108
7109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7110 FL("data:%s"), extra);
7111 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007112 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7114 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7115 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307116 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7117 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 }
7120exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307121 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 if (command)
7123 {
7124 kfree(command);
7125 }
7126 return ret;
7127}
7128
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007129#ifdef CONFIG_COMPAT
7130static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7131{
7132 struct {
7133 compat_uptr_t buf;
7134 int used_len;
7135 int total_len;
7136 } compat_priv_data;
7137 hdd_priv_data_t priv_data;
7138 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007139
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007140 /*
7141 * Note that pAdapter and ifr have already been verified by caller,
7142 * and HDD context has also been validated
7143 */
7144 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7145 sizeof(compat_priv_data))) {
7146 ret = -EFAULT;
7147 goto exit;
7148 }
7149 priv_data.buf = compat_ptr(compat_priv_data.buf);
7150 priv_data.used_len = compat_priv_data.used_len;
7151 priv_data.total_len = compat_priv_data.total_len;
7152 ret = hdd_driver_command(pAdapter, &priv_data);
7153 exit:
7154 return ret;
7155}
7156#else /* CONFIG_COMPAT */
7157static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7158{
7159 /* will never be invoked */
7160 return 0;
7161}
7162#endif /* CONFIG_COMPAT */
7163
7164static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7165{
7166 hdd_priv_data_t priv_data;
7167 int ret = 0;
7168
7169 /*
7170 * Note that pAdapter and ifr have already been verified by caller,
7171 * and HDD context has also been validated
7172 */
7173 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7174 ret = -EFAULT;
7175 } else {
7176 ret = hdd_driver_command(pAdapter, &priv_data);
7177 }
7178 return ret;
7179}
7180
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307181int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007182{
7183 hdd_adapter_t *pAdapter;
7184 hdd_context_t *pHddCtx;
7185 int ret;
7186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307187 ENTER();
7188
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007189 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7190 if (NULL == pAdapter) {
7191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7192 "%s: HDD adapter context is Null", __func__);
7193 ret = -ENODEV;
7194 goto exit;
7195 }
7196 if (dev != pAdapter->dev) {
7197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7198 "%s: HDD adapter/dev inconsistency", __func__);
7199 ret = -ENODEV;
7200 goto exit;
7201 }
7202
7203 if ((!ifr) || (!ifr->ifr_data)) {
7204 ret = -EINVAL;
7205 goto exit;
7206 }
7207
7208 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7209 ret = wlan_hdd_validate_context(pHddCtx);
7210 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007211 ret = -EBUSY;
7212 goto exit;
7213 }
7214
7215 switch (cmd) {
7216 case (SIOCDEVPRIVATE + 1):
7217 if (is_compat_task())
7218 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7219 else
7220 ret = hdd_driver_ioctl(pAdapter, ifr);
7221 break;
7222 default:
7223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7224 __func__, cmd);
7225 ret = -EINVAL;
7226 break;
7227 }
7228 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307229 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007230 return ret;
7231}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007232
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307233int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7234{
7235 int ret;
7236
7237 vos_ssr_protect(__func__);
7238 ret = __hdd_ioctl(dev, ifr, cmd);
7239 vos_ssr_unprotect(__func__);
7240
7241 return ret;
7242}
7243
Katya Nigame7b69a82015-04-28 15:24:06 +05307244int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7245{
7246 return 0;
7247}
7248
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007249#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007250/**---------------------------------------------------------------------------
7251
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007252 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007253
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007254 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007255 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7256 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7257 <space>Scan Mode N<space>Meas Duration N
7258 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7259 then take N.
7260 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7261 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7262 This function does not take care of removing duplicate channels from the list
7263
7264 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007265 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007266
7267 \return - 0 for success non-zero for failure
7268
7269 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007270static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7271 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007272{
7273 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307274 uint8_t input = 0;
7275 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007276 int j = 0, i = 0, v = 0;
7277 char buf[32];
7278
7279 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7280 /*no argument after the command*/
7281 if (NULL == inPtr)
7282 {
7283 return -EINVAL;
7284 }
7285 /*no space after the command*/
7286 else if (SPACE_ASCII_VALUE != *inPtr)
7287 {
7288 return -EINVAL;
7289 }
7290
7291 /*removing empty spaces*/
7292 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7293
7294 /*no argument followed by spaces*/
7295 if ('\0' == *inPtr) return -EINVAL;
7296
7297 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007298 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007299 if (1 != v) return -EINVAL;
7300
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307301 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007302 if ( v < 0) return -EINVAL;
7303
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307304 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7305 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007306
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307307 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7308
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007309
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007310 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007311 {
7312 for (i = 0; i < 4; i++)
7313 {
7314 /*inPtr pointing to the beginning of first space after number of ie fields*/
7315 inPtr = strpbrk( inPtr, " " );
7316 /*no ie data after the number of ie fields argument*/
7317 if (NULL == inPtr) return -EINVAL;
7318
7319 /*removing empty space*/
7320 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7321
7322 /*no ie data after the number of ie fields argument and spaces*/
7323 if ( '\0' == *inPtr ) return -EINVAL;
7324
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007325 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007326 if (1 != v) return -EINVAL;
7327
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307328 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007329 if (v < 0) return -EINVAL;
7330
7331 switch (i)
7332 {
7333 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307334 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007335 {
7336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307337 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007338 return -EINVAL;
7339 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007340 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007341 break;
7342
7343 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307344 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007345 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7346 {
7347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307348 "Invalid Channel Number: %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].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007352 break;
7353
7354 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007355 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007356 {
7357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307358 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007359 return -EINVAL;
7360 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007361 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007362 break;
7363
7364 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307365 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7366 ((pEseBcnReq->bcnReq[j].scanMode == 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 Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007370 return -EINVAL;
7371 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007372 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007373 break;
7374 }
7375 }
7376 }
7377
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007378 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007379 {
7380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307381 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007382 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007383 pEseBcnReq->bcnReq[j].measurementToken,
7384 pEseBcnReq->bcnReq[j].channel,
7385 pEseBcnReq->bcnReq[j].scanMode,
7386 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007387 }
7388
7389 return VOS_STATUS_SUCCESS;
7390}
7391
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307392struct tsm_priv {
7393 tAniTrafStrmMetrics tsm_metrics;
7394};
7395
7396static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7397 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007398{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307399 struct hdd_request *request;
7400 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007401
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307402 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007403
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307404 request = hdd_request_get(context);
7405 if (!request) {
7406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7407 return;
7408 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007409
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307410 priv = hdd_request_priv(request);
7411 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007412
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307413 hdd_request_complete(request);
7414 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007415
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307416 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007417}
7418
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007419static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7420 tAniTrafStrmMetrics* pTsmMetrics)
7421{
7422 hdd_station_ctx_t *pHddStaCtx = NULL;
7423 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007424 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007425 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307426 int ret;
7427 void *cookie;
7428 struct hdd_request *request;
7429 struct tsm_priv *priv;
7430 static const struct hdd_request_params params = {
7431 .priv_size = sizeof(*priv),
7432 .timeout_ms = WLAN_WAIT_TIME_STATS,
7433 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007434
7435 if (NULL == pAdapter)
7436 {
7437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7438 return VOS_STATUS_E_FAULT;
7439 }
7440
7441 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7442 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7443
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307444 request = hdd_request_alloc(&params);
7445 if (!request) {
7446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7447 return VOS_STATUS_E_NOMEM;
7448 }
7449 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007450
7451 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307452 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007453 pHddStaCtx->conn_info.staId[ 0 ],
7454 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307455 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007456
7457 if (eHAL_STATUS_SUCCESS != hstatus)
7458 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7460 __func__);
7461 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007462 }
7463 else
7464 {
7465 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307466 ret = hdd_request_wait_for_response(request);
7467 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007468 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307469 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007470 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307471 } else {
7472 priv = hdd_request_priv(request);
7473 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007474 }
7475 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007476
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307477 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007478
Jeff Johnson72a40512013-12-19 10:14:15 -08007479 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007480}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007481#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007482
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007483#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007484void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7485{
7486 eCsrBand band = -1;
7487 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7488 switch (band)
7489 {
7490 case eCSR_BAND_ALL:
7491 *pBand = WLAN_HDD_UI_BAND_AUTO;
7492 break;
7493
7494 case eCSR_BAND_24:
7495 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7496 break;
7497
7498 case eCSR_BAND_5G:
7499 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7500 break;
7501
7502 default:
7503 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7504 *pBand = -1;
7505 break;
7506 }
7507}
7508
7509/**---------------------------------------------------------------------------
7510
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007511 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7512
7513 This function parses the send action frame data passed in the format
7514 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7515
Srinivas Girigowda56076852013-08-20 14:00:50 -07007516 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007517 \param - pTargetApBssid Pointer to target Ap bssid
7518 \param - pChannel Pointer to the Target AP channel
7519 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7520 \param - pBuf Pointer to data
7521 \param - pBufLen Pointer to data length
7522
7523 \return - 0 for success non-zero for failure
7524
7525 --------------------------------------------------------------------------*/
7526VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7527 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7528{
7529 tANI_U8 *inPtr = pValue;
7530 tANI_U8 *dataEnd;
7531 int tempInt;
7532 int j = 0;
7533 int i = 0;
7534 int v = 0;
7535 tANI_U8 tempBuf[32];
7536 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007537 /* 12 hexa decimal digits, 5 ':' and '\0' */
7538 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007539
7540 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7541 /*no argument after the command*/
7542 if (NULL == inPtr)
7543 {
7544 return -EINVAL;
7545 }
7546
7547 /*no space after the command*/
7548 else if (SPACE_ASCII_VALUE != *inPtr)
7549 {
7550 return -EINVAL;
7551 }
7552
7553 /*removing empty spaces*/
7554 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7555
7556 /*no argument followed by spaces*/
7557 if ('\0' == *inPtr)
7558 {
7559 return -EINVAL;
7560 }
7561
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007562 v = sscanf(inPtr, "%17s", macAddress);
7563 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007564 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7566 "Invalid MAC address or All hex inputs are not read (%d)", v);
7567 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007568 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007569
7570 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7571 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7572 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7573 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7574 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7575 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007576
7577 /* point to the next argument */
7578 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7579 /*no argument after the command*/
7580 if (NULL == inPtr) return -EINVAL;
7581
7582 /*removing empty spaces*/
7583 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7584
7585 /*no argument followed by spaces*/
7586 if ('\0' == *inPtr)
7587 {
7588 return -EINVAL;
7589 }
7590
7591 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007592 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007593 if (1 != v) return -EINVAL;
7594
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007595 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307596 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307597 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007598
7599 *pChannel = tempInt;
7600
7601 /* point to the next argument */
7602 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7603 /*no argument after the command*/
7604 if (NULL == inPtr) return -EINVAL;
7605 /*removing empty spaces*/
7606 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7607
7608 /*no argument followed by spaces*/
7609 if ('\0' == *inPtr)
7610 {
7611 return -EINVAL;
7612 }
7613
7614 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007615 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007616 if (1 != v) return -EINVAL;
7617
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007618 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007619 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007620
7621 *pDwellTime = tempInt;
7622
7623 /* point to the next argument */
7624 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7625 /*no argument after the command*/
7626 if (NULL == inPtr) return -EINVAL;
7627 /*removing empty spaces*/
7628 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7629
7630 /*no argument followed by spaces*/
7631 if ('\0' == *inPtr)
7632 {
7633 return -EINVAL;
7634 }
7635
7636 /* find the length of data */
7637 dataEnd = inPtr;
7638 while(('\0' != *dataEnd) )
7639 {
7640 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007641 }
Kiet Lambe150c22013-11-21 16:30:32 +05307642 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007643 if ( *pBufLen <= 0) return -EINVAL;
7644
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007645 /* Allocate the number of bytes based on the number of input characters
7646 whether it is even or odd.
7647 if the number of input characters are even, then we need N/2 byte.
7648 if the number of input characters are odd, then we need do (N+1)/2 to
7649 compensate rounding off.
7650 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7651 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7652 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007653 if (NULL == *pBuf)
7654 {
7655 hddLog(VOS_TRACE_LEVEL_FATAL,
7656 "%s: vos_mem_alloc failed ", __func__);
7657 return -EINVAL;
7658 }
7659
7660 /* the buffer received from the upper layer is character buffer,
7661 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7662 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7663 and f0 in 3rd location */
7664 for (i = 0, j = 0; j < *pBufLen; j += 2)
7665 {
Kiet Lambe150c22013-11-21 16:30:32 +05307666 if( j+1 == *pBufLen)
7667 {
7668 tempByte = hdd_parse_hex(inPtr[j]);
7669 }
7670 else
7671 {
7672 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7673 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007674 (*pBuf)[i++] = tempByte;
7675 }
7676 *pBufLen = i;
7677 return VOS_STATUS_SUCCESS;
7678}
7679
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007680/**---------------------------------------------------------------------------
7681
Srinivas Girigowdade697412013-02-14 16:31:48 -08007682 \brief hdd_parse_channellist() - HDD Parse channel list
7683
7684 This function parses the channel list passed in the format
7685 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007686 if the Number of channels (N) does not match with the actual number of channels passed
7687 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7688 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7689 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7690 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007691
7692 \param - pValue Pointer to input channel list
7693 \param - ChannelList Pointer to local output array to record channel list
7694 \param - pNumChannels Pointer to number of roam scan channels
7695
7696 \return - 0 for success non-zero for failure
7697
7698 --------------------------------------------------------------------------*/
7699VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7700{
7701 tANI_U8 *inPtr = pValue;
7702 int tempInt;
7703 int j = 0;
7704 int v = 0;
7705 char buf[32];
7706
7707 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7708 /*no argument after the command*/
7709 if (NULL == inPtr)
7710 {
7711 return -EINVAL;
7712 }
7713
7714 /*no space after the command*/
7715 else if (SPACE_ASCII_VALUE != *inPtr)
7716 {
7717 return -EINVAL;
7718 }
7719
7720 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007721 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007722
7723 /*no argument followed by spaces*/
7724 if ('\0' == *inPtr)
7725 {
7726 return -EINVAL;
7727 }
7728
7729 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007730 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007731 if (1 != v) return -EINVAL;
7732
Srinivas Girigowdade697412013-02-14 16:31:48 -08007733 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007734 if ((v < 0) ||
7735 (tempInt <= 0) ||
7736 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7737 {
7738 return -EINVAL;
7739 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007740
7741 *pNumChannels = tempInt;
7742
7743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7744 "Number of channels are: %d", *pNumChannels);
7745
7746 for (j = 0; j < (*pNumChannels); j++)
7747 {
7748 /*inPtr pointing to the beginning of first space after number of channels*/
7749 inPtr = strpbrk( inPtr, " " );
7750 /*no channel list after the number of channels argument*/
7751 if (NULL == inPtr)
7752 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007753 if (0 != j)
7754 {
7755 *pNumChannels = j;
7756 return VOS_STATUS_SUCCESS;
7757 }
7758 else
7759 {
7760 return -EINVAL;
7761 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007762 }
7763
7764 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007765 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007766
7767 /*no channel list after the number of channels argument and spaces*/
7768 if ( '\0' == *inPtr )
7769 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007770 if (0 != j)
7771 {
7772 *pNumChannels = j;
7773 return VOS_STATUS_SUCCESS;
7774 }
7775 else
7776 {
7777 return -EINVAL;
7778 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007779 }
7780
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007781 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007782 if (1 != v) return -EINVAL;
7783
Srinivas Girigowdade697412013-02-14 16:31:48 -08007784 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007785 if ((v < 0) ||
7786 (tempInt <= 0) ||
7787 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7788 {
7789 return -EINVAL;
7790 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007791 pChannelList[j] = tempInt;
7792
7793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7794 "Channel %d added to preferred channel list",
7795 pChannelList[j] );
7796 }
7797
Srinivas Girigowdade697412013-02-14 16:31:48 -08007798 return VOS_STATUS_SUCCESS;
7799}
7800
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007801
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307802/**
7803 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7804 * This function parses the reasoc command data passed in the format
7805 * REASSOC<space><bssid><space><channel>
7806 *
7807 * @pValue: Pointer to input data (its a NUL terminated string)
7808 * @pTargetApBssid: Pointer to target Ap bssid
7809 * @pChannel: Pointer to the Target AP channel
7810 *
7811 * Return: 0 for success non-zero for failure
7812 */
7813static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7814 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007815{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307816 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007817 int tempInt;
7818 int v = 0;
7819 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007820 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007821 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007822
7823 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7824 /*no argument after the command*/
7825 if (NULL == inPtr)
7826 {
7827 return -EINVAL;
7828 }
7829
7830 /*no space after the command*/
7831 else if (SPACE_ASCII_VALUE != *inPtr)
7832 {
7833 return -EINVAL;
7834 }
7835
7836 /*removing empty spaces*/
7837 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7838
7839 /*no argument followed by spaces*/
7840 if ('\0' == *inPtr)
7841 {
7842 return -EINVAL;
7843 }
7844
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007845 v = sscanf(inPtr, "%17s", macAddress);
7846 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007847 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7849 "Invalid MAC address or All hex inputs are not read (%d)", v);
7850 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007851 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007852
7853 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7854 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7855 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7856 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7857 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7858 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007859
7860 /* point to the next argument */
7861 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7862 /*no argument after the command*/
7863 if (NULL == inPtr) return -EINVAL;
7864
7865 /*removing empty spaces*/
7866 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7867
7868 /*no argument followed by spaces*/
7869 if ('\0' == *inPtr)
7870 {
7871 return -EINVAL;
7872 }
7873
7874 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007875 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007876 if (1 != v) return -EINVAL;
7877
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007878 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007879 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307880 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007881 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7882 {
7883 return -EINVAL;
7884 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007885
7886 *pChannel = tempInt;
7887 return VOS_STATUS_SUCCESS;
7888}
7889
7890#endif
7891
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007892#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007893/**---------------------------------------------------------------------------
7894
7895 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7896
7897 This function parses the SETCCKM IE command
7898 SETCCKMIE<space><ie data>
7899
7900 \param - pValue Pointer to input data
7901 \param - pCckmIe Pointer to output cckm Ie
7902 \param - pCckmIeLen Pointer to output cckm ie length
7903
7904 \return - 0 for success non-zero for failure
7905
7906 --------------------------------------------------------------------------*/
7907VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7908 tANI_U8 *pCckmIeLen)
7909{
7910 tANI_U8 *inPtr = pValue;
7911 tANI_U8 *dataEnd;
7912 int j = 0;
7913 int i = 0;
7914 tANI_U8 tempByte = 0;
7915
7916 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7917 /*no argument after the command*/
7918 if (NULL == inPtr)
7919 {
7920 return -EINVAL;
7921 }
7922
7923 /*no space after the command*/
7924 else if (SPACE_ASCII_VALUE != *inPtr)
7925 {
7926 return -EINVAL;
7927 }
7928
7929 /*removing empty spaces*/
7930 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7931
7932 /*no argument followed by spaces*/
7933 if ('\0' == *inPtr)
7934 {
7935 return -EINVAL;
7936 }
7937
7938 /* find the length of data */
7939 dataEnd = inPtr;
7940 while(('\0' != *dataEnd) )
7941 {
7942 dataEnd++;
7943 ++(*pCckmIeLen);
7944 }
7945 if ( *pCckmIeLen <= 0) return -EINVAL;
7946
7947 /* Allocate the number of bytes based on the number of input characters
7948 whether it is even or odd.
7949 if the number of input characters are even, then we need N/2 byte.
7950 if the number of input characters are odd, then we need do (N+1)/2 to
7951 compensate rounding off.
7952 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7953 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7954 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7955 if (NULL == *pCckmIe)
7956 {
7957 hddLog(VOS_TRACE_LEVEL_FATAL,
7958 "%s: vos_mem_alloc failed ", __func__);
7959 return -EINVAL;
7960 }
7961 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7962 /* the buffer received from the upper layer is character buffer,
7963 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7964 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7965 and f0 in 3rd location */
7966 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7967 {
7968 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7969 (*pCckmIe)[i++] = tempByte;
7970 }
7971 *pCckmIeLen = i;
7972
7973 return VOS_STATUS_SUCCESS;
7974}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007975#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007976
Jeff Johnson295189b2012-06-20 16:38:30 -07007977/**---------------------------------------------------------------------------
7978
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007979 \brief hdd_is_valid_mac_address() - Validate MAC address
7980
7981 This function validates whether the given MAC address is valid or not
7982 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7983 where X is the hexa decimal digit character and separated by ':'
7984 This algorithm works even if MAC address is not separated by ':'
7985
7986 This code checks given input string mac contains exactly 12 hexadecimal digits.
7987 and a separator colon : appears in the input string only after
7988 an even number of hex digits.
7989
7990 \param - pMacAddr pointer to the input MAC address
7991 \return - 1 for valid and 0 for invalid
7992
7993 --------------------------------------------------------------------------*/
7994
7995v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7996{
7997 int xdigit = 0;
7998 int separator = 0;
7999 while (*pMacAddr)
8000 {
8001 if (isxdigit(*pMacAddr))
8002 {
8003 xdigit++;
8004 }
8005 else if (':' == *pMacAddr)
8006 {
8007 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8008 break;
8009
8010 ++separator;
8011 }
8012 else
8013 {
8014 separator = -1;
8015 /* Invalid MAC found */
8016 return 0;
8017 }
8018 ++pMacAddr;
8019 }
8020 return (xdigit == 12 && (separator == 5 || separator == 0));
8021}
8022
8023/**---------------------------------------------------------------------------
8024
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308025 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008026
8027 \param - dev Pointer to net_device structure
8028
8029 \return - 0 for success non-zero for failure
8030
8031 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308032int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008033{
8034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8035 hdd_context_t *pHddCtx;
8036 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8037 VOS_STATUS status;
8038 v_BOOL_t in_standby = TRUE;
8039
8040 if (NULL == pAdapter)
8041 {
8042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308043 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 return -ENODEV;
8045 }
8046
8047 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308048 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8049 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 if (NULL == pHddCtx)
8051 {
8052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008053 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 return -ENODEV;
8055 }
8056
8057 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8058 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8059 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008060 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8061 {
8062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308063 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008064 in_standby = FALSE;
8065 break;
8066 }
8067 else
8068 {
8069 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8070 pAdapterNode = pNext;
8071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 }
8073
8074 if (TRUE == in_standby)
8075 {
8076 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8077 {
8078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8079 "wlan out of power save", __func__);
8080 return -EINVAL;
8081 }
8082 }
8083
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008084 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8086 {
8087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008088 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 netif_tx_start_all_queues(dev);
8092 }
8093
8094 return 0;
8095}
8096
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308097/**---------------------------------------------------------------------------
8098
8099 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8100
8101 This is called in response to ifconfig up
8102
8103 \param - dev Pointer to net_device structure
8104
8105 \return - 0 for success non-zero for failure
8106
8107 --------------------------------------------------------------------------*/
8108int hdd_open(struct net_device *dev)
8109{
8110 int ret;
8111
8112 vos_ssr_protect(__func__);
8113 ret = __hdd_open(dev);
8114 vos_ssr_unprotect(__func__);
8115
8116 return ret;
8117}
8118
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308119int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008120{
8121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308122 hdd_adapter_t *sta_adapter;
8123 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008124
8125 if(pAdapter == NULL) {
8126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008127 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008128 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 }
8130
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308131 if (vos_get_concurrency_mode() != VOS_STA_MON)
8132 return 0;
8133
8134 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8135 if (wlan_hdd_validate_context(hdd_ctx))
8136 return -EINVAL;
8137
8138 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8139 if (!sta_adapter) {
8140 hddLog(LOGE, FL("No valid STA interface"));
8141 return -EINVAL;
8142 }
8143
8144 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8145 hddLog(LOGE, FL("STA Interface is not OPENED"));
8146 return -EINVAL;
8147 }
8148
8149 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8150
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 return 0;
8152}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308153
8154int hdd_mon_open (struct net_device *dev)
8155{
8156 int ret;
8157
8158 vos_ssr_protect(__func__);
8159 ret = __hdd_mon_open(dev);
8160 vos_ssr_unprotect(__func__);
8161
8162 return ret;
8163}
8164
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308165int __hdd_mon_stop (struct net_device *dev)
8166{
8167 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8168 hdd_context_t *hdd_ctx;
8169
8170 if (vos_get_concurrency_mode() != VOS_STA_MON)
8171 return 0;
8172
8173 if(!mon_adapter) {
8174 hddLog(LOGE, FL("HDD adapter is Null"));
8175 return -EINVAL;
8176 }
8177
8178 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8179 if (wlan_hdd_validate_context(hdd_ctx))
8180 return -EINVAL;
8181
8182 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8183 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8184 return -ENODEV;
8185 }
8186
8187 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8188 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8189
8190 return 0;
8191}
8192
Katya Nigame7b69a82015-04-28 15:24:06 +05308193int hdd_mon_stop(struct net_device *dev)
8194{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308195 int ret;
8196
8197 vos_ssr_protect(__func__);
8198 ret = __hdd_mon_stop(dev);
8199 vos_ssr_unprotect(__func__);
8200
8201 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308202}
8203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204/**---------------------------------------------------------------------------
8205
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308206 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008207
8208 \param - dev Pointer to net_device structure
8209
8210 \return - 0 for success non-zero for failure
8211
8212 --------------------------------------------------------------------------*/
8213
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308214int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008215{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308216 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8218 hdd_context_t *pHddCtx;
8219 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8220 VOS_STATUS status;
8221 v_BOOL_t enter_standby = TRUE;
8222
8223 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 if (NULL == pAdapter)
8225 {
8226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308227 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 return -ENODEV;
8229 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308230 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308231 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308232
8233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8234 ret = wlan_hdd_validate_context(pHddCtx);
8235 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308237 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
8239
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308240 /* Nothing to be done if the interface is not opened */
8241 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8242 {
8243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8244 "%s: NETDEV Interface is not OPENED", __func__);
8245 return -ENODEV;
8246 }
8247
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308248 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308249 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308250 * In STA + Monitor mode concurrency, no point in running
8251 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308252 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308253 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308254 }
8255
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308256 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008257 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308259
8260 /* Disable TX on the interface, after this hard_start_xmit() will not
8261 * be called on that interface
8262 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308265
8266 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 netif_carrier_off(pAdapter->dev);
8268
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308269 /* The interface is marked as down for outside world (aka kernel)
8270 * But the driver is pretty much alive inside. The driver needs to
8271 * tear down the existing connection on the netdev (session)
8272 * cleanup the data pipes and wait until the control plane is stabilized
8273 * for this interface. The call also needs to wait until the above
8274 * mentioned actions are completed before returning to the caller.
8275 * Notice that the hdd_stop_adapter is requested not to close the session
8276 * That is intentional to be able to scan if it is a STA/P2P interface
8277 */
8278 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308279#ifdef FEATURE_WLAN_TDLS
8280 mutex_lock(&pHddCtx->tdls_lock);
8281#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308282 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308283 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308284#ifdef FEATURE_WLAN_TDLS
8285 mutex_unlock(&pHddCtx->tdls_lock);
8286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 /* SoftAP ifaces should never go in power save mode
8288 making sure same here. */
8289 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 )
8292 {
8293 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8295 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 EXIT();
8297 return 0;
8298 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308299 /* Find if any iface is up. If any iface is up then can't put device to
8300 * sleep/power save mode
8301 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8303 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8304 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008305 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8306 {
8307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308308 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008309 enter_standby = FALSE;
8310 break;
8311 }
8312 else
8313 {
8314 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8315 pAdapterNode = pNext;
8316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 }
8318
8319 if (TRUE == enter_standby)
8320 {
8321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8322 "entering standby", __func__);
8323 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8324 {
8325 /*log and return success*/
8326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8327 "wlan in power save", __func__);
8328 }
8329 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308330
8331 /*
8332 * Upon wifi turn off, DUT has to flush the scan results so if
8333 * this is the last cli iface, flush the scan database.
8334 */
8335 if (!hdd_is_cli_iface_up(pHddCtx))
8336 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008337
8338 EXIT();
8339 return 0;
8340}
8341
8342/**---------------------------------------------------------------------------
8343
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308344 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008345
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308346 This is called in response to ifconfig down
8347
8348 \param - dev Pointer to net_device structure
8349
8350 \return - 0 for success non-zero for failure
8351-----------------------------------------------------------------------------*/
8352int hdd_stop (struct net_device *dev)
8353{
8354 int ret;
8355
8356 vos_ssr_protect(__func__);
8357 ret = __hdd_stop(dev);
8358 vos_ssr_unprotect(__func__);
8359
8360 return ret;
8361}
8362
8363/**---------------------------------------------------------------------------
8364
8365 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008366
8367 \param - dev Pointer to net_device structure
8368
8369 \return - void
8370
8371 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308372static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008373{
8374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308375 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 ENTER();
8377
8378 do
8379 {
8380 if (NULL == pAdapter)
8381 {
8382 hddLog(VOS_TRACE_LEVEL_FATAL,
8383 "%s: NULL pAdapter", __func__);
8384 break;
8385 }
8386
8387 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8388 {
8389 hddLog(VOS_TRACE_LEVEL_FATAL,
8390 "%s: Invalid magic", __func__);
8391 break;
8392 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8394 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 {
8396 hddLog(VOS_TRACE_LEVEL_FATAL,
8397 "%s: NULL pHddCtx", __func__);
8398 break;
8399 }
8400
8401 if (dev != pAdapter->dev)
8402 {
8403 hddLog(VOS_TRACE_LEVEL_FATAL,
8404 "%s: Invalid device reference", __func__);
8405 /* we haven't validated all cases so let this go for now */
8406 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308407#ifdef FEATURE_WLAN_TDLS
8408 mutex_lock(&pHddCtx->tdls_lock);
8409#endif
c_hpothu002231a2015-02-05 14:58:51 +05308410 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308411#ifdef FEATURE_WLAN_TDLS
8412 mutex_unlock(&pHddCtx->tdls_lock);
8413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
8415 /* after uninit our adapter structure will no longer be valid */
8416 pAdapter->dev = NULL;
8417 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308418 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 } while (0);
8420
8421 EXIT();
8422}
8423
8424/**---------------------------------------------------------------------------
8425
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308426 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8427
8428 This is called during the netdev unregister to uninitialize all data
8429associated with the device
8430
8431 \param - dev Pointer to net_device structure
8432
8433 \return - void
8434
8435 --------------------------------------------------------------------------*/
8436static void hdd_uninit (struct net_device *dev)
8437{
8438 vos_ssr_protect(__func__);
8439 __hdd_uninit(dev);
8440 vos_ssr_unprotect(__func__);
8441}
8442
8443/**---------------------------------------------------------------------------
8444
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 \brief hdd_release_firmware() -
8446
8447 This function calls the release firmware API to free the firmware buffer.
8448
8449 \param - pFileName Pointer to the File Name.
8450 pCtx - Pointer to the adapter .
8451
8452
8453 \return - 0 for success, non zero for failure
8454
8455 --------------------------------------------------------------------------*/
8456
8457VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8458{
8459 VOS_STATUS status = VOS_STATUS_SUCCESS;
8460 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8461 ENTER();
8462
8463
8464 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8465
8466 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8467
8468 if(pHddCtx->fw) {
8469 release_firmware(pHddCtx->fw);
8470 pHddCtx->fw = NULL;
8471 }
8472 else
8473 status = VOS_STATUS_E_FAILURE;
8474 }
8475 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8476 if(pHddCtx->nv) {
8477 release_firmware(pHddCtx->nv);
8478 pHddCtx->nv = NULL;
8479 }
8480 else
8481 status = VOS_STATUS_E_FAILURE;
8482
8483 }
8484
8485 EXIT();
8486 return status;
8487}
8488
8489/**---------------------------------------------------------------------------
8490
8491 \brief hdd_request_firmware() -
8492
8493 This function reads the firmware file using the request firmware
8494 API and returns the the firmware data and the firmware file size.
8495
8496 \param - pfileName - Pointer to the file name.
8497 - pCtx - Pointer to the adapter .
8498 - ppfw_data - Pointer to the pointer of the firmware data.
8499 - pSize - Pointer to the file size.
8500
8501 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8502
8503 --------------------------------------------------------------------------*/
8504
8505
8506VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8507{
8508 int status;
8509 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8510 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8511 ENTER();
8512
8513 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8514
8515 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8516
8517 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8518 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8519 __func__, pfileName);
8520 retval = VOS_STATUS_E_FAILURE;
8521 }
8522
8523 else {
8524 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8525 *pSize = pHddCtx->fw->size;
8526 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8527 __func__, *pSize);
8528 }
8529 }
8530 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8531
8532 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8533
8534 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8536 __func__, pfileName);
8537 retval = VOS_STATUS_E_FAILURE;
8538 }
8539
8540 else {
8541 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8542 *pSize = pHddCtx->nv->size;
8543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8544 __func__, *pSize);
8545 }
8546 }
8547
8548 EXIT();
8549 return retval;
8550}
8551/**---------------------------------------------------------------------------
8552 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8553
8554 This is the function invoked by SME to inform the result of a full power
8555 request issued by HDD
8556
8557 \param - callbackcontext - Pointer to cookie
8558 status - result of request
8559
8560 \return - None
8561
8562--------------------------------------------------------------------------*/
8563void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8564{
8565 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8566
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 if(&pHddCtx->full_pwr_comp_var)
8569 {
8570 complete(&pHddCtx->full_pwr_comp_var);
8571 }
8572}
8573
Abhishek Singh00b71972016-01-07 10:51:04 +05308574#ifdef WLAN_FEATURE_RMC
8575static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8576{
8577 int payload_len;
8578 struct sk_buff *skb;
8579 struct nlmsghdr *nlh;
8580 v_U8_t *data;
8581
8582 payload_len = ETH_ALEN;
8583
8584 if (0 == cesium_pid)
8585 {
8586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8587 __func__);
8588 return;
8589 }
8590
8591 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8592 {
8593 hddLog(VOS_TRACE_LEVEL_ERROR,
8594 "%s: nlmsg_new() failed for msg size[%d]",
8595 __func__, NLMSG_SPACE(payload_len));
8596 return;
8597 }
8598
8599 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8600
8601 if (NULL == nlh)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_ERROR,
8604 "%s: nlmsg_put() failed for msg size[%d]",
8605 __func__, NLMSG_SPACE(payload_len));
8606
8607 kfree_skb(skb);
8608 return;
8609 }
8610
8611 data = nlmsg_data(nlh);
8612 memcpy(data, MacAddr, ETH_ALEN);
8613
8614 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8615 {
8616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8617 __func__, NLMSG_SPACE(payload_len));
8618 }
8619
8620 return;
8621}
8622
8623/**---------------------------------------------------------------------------
8624 \brief hdd_ParseuserParams - return a pointer to the next argument
8625
8626 \return - status
8627
8628--------------------------------------------------------------------------*/
8629static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8630{
8631 tANI_U8 *pVal;
8632
8633 pVal = strchr(pValue, ' ');
8634
8635 if (NULL == pVal)
8636 {
8637 /* no argument remains */
8638 return -EINVAL;
8639 }
8640 else if (SPACE_ASCII_VALUE != *pVal)
8641 {
8642 /* no space after the current argument */
8643 return -EINVAL;
8644 }
8645
8646 pVal++;
8647
8648 /* remove empty spaces */
8649 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8650 {
8651 pVal++;
8652 }
8653
8654 /* no argument followed by spaces */
8655 if ('\0' == *pVal)
8656 {
8657 return -EINVAL;
8658 }
8659
8660 *ppArg = pVal;
8661
8662 return 0;
8663}
8664
8665/**----------------------------------------------------------------------------
8666 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8667
8668 \return - status
8669
8670------------------------------------------------------------------------------*/
8671static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8672 tANI_U8 *tx_fail_count,
8673 tANI_U16 *pid)
8674{
8675 tANI_U8 *param = NULL;
8676 int ret;
8677
8678 ret = hdd_ParseUserParams(pValue, &param);
8679
8680 if (0 == ret && NULL != param)
8681 {
8682 if (1 != sscanf(param, "%hhu", tx_fail_count))
8683 {
8684 ret = -EINVAL;
8685 goto done;
8686 }
8687 }
8688 else
8689 {
8690 goto done;
8691 }
8692
8693 if (0 == *tx_fail_count)
8694 {
8695 *pid = 0;
8696 goto done;
8697 }
8698
8699 pValue = param;
8700 pValue++;
8701
8702 ret = hdd_ParseUserParams(pValue, &param);
8703
8704 if (0 == ret)
8705 {
8706 if (1 != sscanf(param, "%hu", pid))
8707 {
8708 ret = -EINVAL;
8709 goto done;
8710 }
8711 }
8712 else
8713 {
8714 goto done;
8715 }
8716
8717done:
8718 return ret;
8719}
8720
8721static int hdd_open_cesium_nl_sock()
8722{
8723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8724 struct netlink_kernel_cfg cfg = {
8725 .groups = WLAN_NLINK_MCAST_GRP_ID,
8726 .input = NULL
8727 };
8728#endif
8729 int ret = 0;
8730
8731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8732 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8733#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8734 THIS_MODULE,
8735#endif
8736 &cfg);
8737#else
8738 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8739 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8740#endif
8741
8742 if (cesium_nl_srv_sock == NULL)
8743 {
8744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8745 "NLINK: cesium netlink_kernel_create failed");
8746 ret = -ECONNREFUSED;
8747 }
8748
8749 return ret;
8750}
8751
8752static void hdd_close_cesium_nl_sock()
8753{
8754 if (NULL != cesium_nl_srv_sock)
8755 {
8756 netlink_kernel_release(cesium_nl_srv_sock);
8757 cesium_nl_srv_sock = NULL;
8758 }
8759}
8760#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008761/**---------------------------------------------------------------------------
8762
8763 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8764
8765 This is the function invoked by SME to inform the result of BMPS
8766 request issued by HDD
8767
8768 \param - callbackcontext - Pointer to cookie
8769 status - result of request
8770
8771 \return - None
8772
8773--------------------------------------------------------------------------*/
8774void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8775{
8776
8777 struct completion *completion_var = (struct completion*) callbackContext;
8778
Arif Hussain6d2a3322013-11-17 19:50:10 -08008779 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 if(completion_var != NULL)
8781 {
8782 complete(completion_var);
8783 }
8784}
8785
8786/**---------------------------------------------------------------------------
8787
8788 \brief hdd_get_cfg_file_size() -
8789
8790 This function reads the configuration file using the request firmware
8791 API and returns the configuration file size.
8792
8793 \param - pCtx - Pointer to the adapter .
8794 - pFileName - Pointer to the file name.
8795 - pBufSize - Pointer to the buffer size.
8796
8797 \return - 0 for success, non zero for failure
8798
8799 --------------------------------------------------------------------------*/
8800
8801VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8802{
8803 int status;
8804 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8805
8806 ENTER();
8807
8808 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8809
8810 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8811 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8812 status = VOS_STATUS_E_FAILURE;
8813 }
8814 else {
8815 *pBufSize = pHddCtx->fw->size;
8816 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8817 release_firmware(pHddCtx->fw);
8818 pHddCtx->fw = NULL;
8819 }
8820
8821 EXIT();
8822 return VOS_STATUS_SUCCESS;
8823}
8824
8825/**---------------------------------------------------------------------------
8826
8827 \brief hdd_read_cfg_file() -
8828
8829 This function reads the configuration file using the request firmware
8830 API and returns the cfg data and the buffer size of the configuration file.
8831
8832 \param - pCtx - Pointer to the adapter .
8833 - pFileName - Pointer to the file name.
8834 - pBuffer - Pointer to the data buffer.
8835 - pBufSize - Pointer to the buffer size.
8836
8837 \return - 0 for success, non zero for failure
8838
8839 --------------------------------------------------------------------------*/
8840
8841VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8842 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8843{
8844 int status;
8845 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8846
8847 ENTER();
8848
8849 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8850
8851 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8852 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8853 return VOS_STATUS_E_FAILURE;
8854 }
8855 else {
8856 if(*pBufSize != pHddCtx->fw->size) {
8857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8858 "file size", __func__);
8859 release_firmware(pHddCtx->fw);
8860 pHddCtx->fw = NULL;
8861 return VOS_STATUS_E_FAILURE;
8862 }
8863 else {
8864 if(pBuffer) {
8865 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8866 }
8867 release_firmware(pHddCtx->fw);
8868 pHddCtx->fw = NULL;
8869 }
8870 }
8871
8872 EXIT();
8873
8874 return VOS_STATUS_SUCCESS;
8875}
8876
8877/**---------------------------------------------------------------------------
8878
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308879 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008880
8881 This function sets the user specified mac address using
8882 the command ifconfig wlanX hw ether <mac adress>.
8883
8884 \param - dev - Pointer to the net device.
8885 - addr - Pointer to the sockaddr.
8886 \return - 0 for success, non zero for failure
8887
8888 --------------------------------------------------------------------------*/
8889
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308890static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308892 hdd_adapter_t *pAdapter;
8893 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 struct sockaddr *psta_mac_addr = addr;
8895 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308896 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008897
8898 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308899 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8900 if (NULL == pAdapter)
8901 {
8902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8903 "%s: Adapter is NULL",__func__);
8904 return -EINVAL;
8905 }
8906 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8907 ret = wlan_hdd_validate_context(pHddCtx);
8908 if (0 != ret)
8909 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308910 return ret;
8911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8915
8916 EXIT();
8917 return halStatus;
8918}
8919
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308920/**---------------------------------------------------------------------------
8921
8922 \brief hdd_set_mac_address() -
8923
8924 Wrapper function to protect __hdd_set_mac_address() function from ssr
8925
8926 \param - dev - Pointer to the net device.
8927 - addr - Pointer to the sockaddr.
8928 \return - 0 for success, non zero for failure
8929
8930 --------------------------------------------------------------------------*/
8931static int hdd_set_mac_address(struct net_device *dev, void *addr)
8932{
8933 int ret;
8934
8935 vos_ssr_protect(__func__);
8936 ret = __hdd_set_mac_address(dev, addr);
8937 vos_ssr_unprotect(__func__);
8938
8939 return ret;
8940}
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8943{
8944 int i;
8945 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8946 {
Abhishek Singheb183782014-02-06 13:37:21 +05308947 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 break;
8949 }
8950
8951 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8952 return NULL;
8953
8954 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8955 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8956}
8957
8958void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8959{
8960 int i;
8961 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8962 {
8963 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8964 {
8965 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8966 break;
8967 }
8968 }
8969 return;
8970}
8971
8972#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8973 static struct net_device_ops wlan_drv_ops = {
8974 .ndo_open = hdd_open,
8975 .ndo_stop = hdd_stop,
8976 .ndo_uninit = hdd_uninit,
8977 .ndo_start_xmit = hdd_hard_start_xmit,
8978 .ndo_tx_timeout = hdd_tx_timeout,
8979 .ndo_get_stats = hdd_stats,
8980 .ndo_do_ioctl = hdd_ioctl,
8981 .ndo_set_mac_address = hdd_set_mac_address,
8982 .ndo_select_queue = hdd_select_queue,
8983#ifdef WLAN_FEATURE_PACKET_FILTERING
8984#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8985 .ndo_set_rx_mode = hdd_set_multicast_list,
8986#else
8987 .ndo_set_multicast_list = hdd_set_multicast_list,
8988#endif //LINUX_VERSION_CODE
8989#endif
8990 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 static struct net_device_ops wlan_mon_drv_ops = {
8992 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308993 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 .ndo_uninit = hdd_uninit,
8995 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8996 .ndo_tx_timeout = hdd_tx_timeout,
8997 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308998 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 .ndo_set_mac_address = hdd_set_mac_address,
9000 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002#endif
9003
9004void hdd_set_station_ops( struct net_device *pWlanDev )
9005{
9006#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 pWlanDev->netdev_ops = &wlan_drv_ops;
9008#else
9009 pWlanDev->open = hdd_open;
9010 pWlanDev->stop = hdd_stop;
9011 pWlanDev->uninit = hdd_uninit;
9012 pWlanDev->hard_start_xmit = NULL;
9013 pWlanDev->tx_timeout = hdd_tx_timeout;
9014 pWlanDev->get_stats = hdd_stats;
9015 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 pWlanDev->set_mac_address = hdd_set_mac_address;
9017#endif
9018}
9019
Katya Nigam1fd24402015-02-16 14:52:19 +05309020void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9021{
9022 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9023 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9024 #else
9025 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9026 #endif
9027}
9028
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009029static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009030{
9031 struct net_device *pWlanDev = NULL;
9032 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 /*
9034 * cfg80211 initialization and registration....
9035 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309036 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9037#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9038 NET_NAME_UNKNOWN,
9039#endif
9040 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 if(pWlanDev != NULL)
9042 {
9043
9044 //Save the pointer to the net_device in the HDD adapter
9045 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9046
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9048
9049 pAdapter->dev = pWlanDev;
9050 pAdapter->pHddCtx = pHddCtx;
9051 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309052 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009053
Rajeev79dbe4c2013-10-05 11:03:42 +05309054#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309055 pAdapter->pBatchScanRsp = NULL;
9056 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009057 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009058 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309059 mutex_init(&pAdapter->hdd_batch_scan_lock);
9060#endif
9061
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 pAdapter->isLinkUpSvcNeeded = FALSE;
9063 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9064 //Init the net_device structure
9065 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9066
9067 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9068 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9069 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309070
9071 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009072
9073 hdd_set_station_ops( pAdapter->dev );
9074
9075 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9077 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9078 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 /* set pWlanDev's parent to underlying device */
9080 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009081
9082 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 }
9084
9085 return pAdapter;
9086}
9087
9088VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9089{
9090 struct net_device *pWlanDev = pAdapter->dev;
9091 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9092 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9093 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9094
9095 if( rtnl_lock_held )
9096 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009097 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9099 {
9100 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9101 return VOS_STATUS_E_FAILURE;
9102 }
9103 }
9104 if (register_netdevice(pWlanDev))
9105 {
9106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9107 return VOS_STATUS_E_FAILURE;
9108 }
9109 }
9110 else
9111 {
9112 if(register_netdev(pWlanDev))
9113 {
9114 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9115 return VOS_STATUS_E_FAILURE;
9116 }
9117 }
9118 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9119
9120 return VOS_STATUS_SUCCESS;
9121}
9122
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009123static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009124{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009125 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009126
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009127 if (NULL == pAdapter)
9128 {
9129 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9130 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009132
9133 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9134 {
9135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9136 return eHAL_STATUS_NOT_INITIALIZED;
9137 }
9138
9139 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9140
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009141#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009142 /* need to make sure all of our scheduled work has completed.
9143 * This callback is called from MC thread context, so it is safe to
9144 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009145 *
9146 * Even though this is called from MC thread context, if there is a faulty
9147 * work item in the system, that can hang this call forever. So flushing
9148 * this global work queue is not safe; and now we make sure that
9149 * individual work queues are stopped correctly. But the cancel work queue
9150 * is a GPL only API, so the proprietary version of the driver would still
9151 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009152 */
9153 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009154#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009155
9156 /* We can be blocked while waiting for scheduled work to be
9157 * flushed, and the adapter structure can potentially be freed, in
9158 * which case the magic will have been reset. So make sure the
9159 * magic is still good, and hence the adapter structure is still
9160 * valid, before signaling completion */
9161 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9162 {
9163 complete(&pAdapter->session_close_comp_var);
9164 }
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 return eHAL_STATUS_SUCCESS;
9167}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309168/**
9169 * hdd_close_tx_queues() - close tx queues
9170 * @hdd_ctx: hdd global context
9171 *
9172 * Return: None
9173 */
9174static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9175{
9176 VOS_STATUS status;
9177 hdd_adapter_t *adapter;
9178 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9179 /* Not validating hdd_ctx as it's already done by the caller */
9180 ENTER();
9181 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9182 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9183 adapter = adapter_node->pAdapter;
9184 if (adapter && adapter->dev) {
9185 netif_tx_disable (adapter->dev);
9186 netif_carrier_off(adapter->dev);
9187 }
9188 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9189 &next_adapter);
9190 adapter_node = next_adapter;
9191 }
9192 EXIT();
9193}
Jeff Johnson295189b2012-06-20 16:38:30 -07009194
9195VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9196{
9197 struct net_device *pWlanDev = pAdapter->dev;
9198 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9200 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9201 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309202 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
Nirav Shah7e3c8132015-06-22 23:51:42 +05309204 spin_lock_init( &pAdapter->sta_hash_lock);
9205 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009208 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 //Open a SME session for future operation
9210 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009211 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9213 {
9214 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009215 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 halStatus, halStatus );
9217 status = VOS_STATUS_E_FAILURE;
9218 goto error_sme_open;
9219 }
9220
9221 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309222 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 &pAdapter->session_open_comp_var,
9224 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309225 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 {
9227 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309228 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 status = VOS_STATUS_E_FAILURE;
9230 goto error_sme_open;
9231 }
9232
9233 // Register wireless extensions
9234 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9235 {
9236 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009237 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 halStatus, halStatus );
9239 status = VOS_STATUS_E_FAILURE;
9240 goto error_register_wext;
9241 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309242
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309244 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9245 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9246 #else
9247 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9248 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
9250 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309251 hddLog(VOS_TRACE_LEVEL_INFO,
9252 "%s: Set HDD connState to eConnectionState_NotConnected",
9253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9255
9256 //Set the default operation channel
9257 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9258
9259 /* Make the default Auth Type as OPEN*/
9260 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9261
9262 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9263 {
9264 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009265 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 status, status );
9267 goto error_init_txrx;
9268 }
9269
9270 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9271
9272 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9273 {
9274 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009275 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 status, status );
9277 goto error_wmm_init;
9278 }
9279
9280 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9281
9282 return VOS_STATUS_SUCCESS;
9283
9284error_wmm_init:
9285 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9286 hdd_deinit_tx_rx(pAdapter);
9287error_init_txrx:
9288 hdd_UnregisterWext(pWlanDev);
9289error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009290 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 {
9292 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009293 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309294 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009295 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309297 unsigned long rc;
9298
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309300 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009302 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309303 if (rc <= 0)
9304 hddLog(VOS_TRACE_LEVEL_ERROR,
9305 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 }
9307}
9308error_sme_open:
9309 return status;
9310}
9311
Jeff Johnson295189b2012-06-20 16:38:30 -07009312void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9313{
9314 hdd_cfg80211_state_t *cfgState;
9315
9316 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9317
9318 if( NULL != cfgState->buf )
9319 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309320 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9322 rc = wait_for_completion_interruptible_timeout(
9323 &pAdapter->tx_action_cnf_event,
9324 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309325 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9328 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9329 , __func__, rc);
9330
9331 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9332 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 }
9334 }
9335 return;
9336}
Jeff Johnson295189b2012-06-20 16:38:30 -07009337
c_hpothu002231a2015-02-05 14:58:51 +05309338void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009339{
9340 ENTER();
9341 switch ( pAdapter->device_mode )
9342 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309343 case WLAN_HDD_IBSS:
9344 {
9345 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9346 {
9347 hdd_ibss_deinit_tx_rx( pAdapter );
9348 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9349 }
9350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 case WLAN_HDD_INFRA_STATION:
9352 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009353 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 {
9355 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9356 {
9357 hdd_deinit_tx_rx( pAdapter );
9358 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9359 }
9360
9361 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9362 {
9363 hdd_wmm_adapter_close( pAdapter );
9364 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9365 }
9366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 break;
9369 }
9370
9371 case WLAN_HDD_SOFTAP:
9372 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309374
9375 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9376 {
9377 hdd_wmm_adapter_close( pAdapter );
9378 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9379 }
9380
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009382
c_hpothu002231a2015-02-05 14:58:51 +05309383 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309384 /* set con_mode to STA only when no SAP concurrency mode */
9385 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9386 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 break;
9388 }
9389
9390 case WLAN_HDD_MONITOR:
9391 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9393 {
9394 hdd_deinit_tx_rx( pAdapter );
9395 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 break;
9398 }
9399
9400
9401 default:
9402 break;
9403 }
9404
9405 EXIT();
9406}
9407
9408void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9409{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009410 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309411
9412 ENTER();
9413 if (NULL == pAdapter)
9414 {
9415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9416 "%s: HDD adapter is Null", __func__);
9417 return;
9418 }
9419
9420 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
Rajeev79dbe4c2013-10-05 11:03:42 +05309422#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309423 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9424 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009425 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309426 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9427 )
9428 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009429 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309430 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009431 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9432 {
9433 hdd_deinit_batch_scan(pAdapter);
9434 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309435 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009436 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309437#endif
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9440 if( rtnl_held )
9441 {
9442 unregister_netdevice(pWlanDev);
9443 }
9444 else
9445 {
9446 unregister_netdev(pWlanDev);
9447 }
9448 // note that the pAdapter is no longer valid at this point
9449 // since the memory has been reclaimed
9450 }
9451
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309452 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009453}
9454
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009455void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9456{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309457 VOS_STATUS status;
9458 hdd_adapter_t *pAdapter = NULL;
9459 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009460
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309461 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009462
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309463 /*loop through all adapters.*/
9464 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009465 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309466 pAdapter = pAdapterNode->pAdapter;
9467 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9468 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009469
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309470 { // we skip this registration for modes other than STA and P2P client modes.
9471 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9472 pAdapterNode = pNext;
9473 continue;
9474 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009475
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309476 //Apply Dynamic DTIM For P2P
9477 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9478 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9479 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9480 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9481 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9482 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9483 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9484 (eConnectionState_Associated ==
9485 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9486 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9487 {
9488 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009489
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309490 powerRequest.uIgnoreDTIM = 1;
9491 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9492
9493 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9494 {
9495 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9496 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9497 }
9498 else
9499 {
9500 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9501 }
9502
9503 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9504 * specified during Enter/Exit BMPS when LCD off*/
9505 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9506 NULL, eANI_BOOLEAN_FALSE);
9507 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9508 NULL, eANI_BOOLEAN_FALSE);
9509
9510 /* switch to the DTIM specified in cfg.ini */
9511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309512 "Switch to DTIM %d Listen interval %d",
9513 powerRequest.uDTIMPeriod,
9514 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309515 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9516 break;
9517
9518 }
9519
9520 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9521 pAdapterNode = pNext;
9522 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009523}
9524
9525void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9526{
9527 /*Switch back to DTIM 1*/
9528 tSirSetPowerParamsReq powerRequest = { 0 };
9529
9530 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9531 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009532 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009533
9534 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9535 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9536 NULL, eANI_BOOLEAN_FALSE);
9537 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9538 NULL, eANI_BOOLEAN_FALSE);
9539
9540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9541 "Switch to DTIM%d",powerRequest.uListenInterval);
9542 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9543
9544}
9545
Jeff Johnson295189b2012-06-20 16:38:30 -07009546VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9547{
9548 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309549 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9550 {
9551 hddLog( LOGE, FL("Wlan Unload in progress"));
9552 return VOS_STATUS_E_PERM;
9553 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309554
9555 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9556 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9557 return VOS_STATUS_SUCCESS;
9558 }
9559
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9561 {
9562 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9563 }
9564
9565 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9566 {
9567 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9568 }
9569
9570 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9571 {
9572 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9573 }
9574
9575 return status;
9576}
9577
9578VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9579{
9580 hdd_adapter_t *pAdapter = NULL;
9581 eHalStatus halStatus;
9582 VOS_STATUS status = VOS_STATUS_E_INVAL;
9583 v_BOOL_t disableBmps = FALSE;
9584 v_BOOL_t disableImps = FALSE;
9585
9586 switch(session_type)
9587 {
9588 case WLAN_HDD_INFRA_STATION:
9589 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 case WLAN_HDD_P2P_CLIENT:
9591 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 //Exit BMPS -> Is Sta/P2P Client is already connected
9593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9594 if((NULL != pAdapter)&&
9595 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9596 {
9597 disableBmps = TRUE;
9598 }
9599
9600 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9601 if((NULL != pAdapter)&&
9602 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9603 {
9604 disableBmps = TRUE;
9605 }
9606
9607 //Exit both Bmps and Imps incase of Go/SAP Mode
9608 if((WLAN_HDD_SOFTAP == session_type) ||
9609 (WLAN_HDD_P2P_GO == session_type))
9610 {
9611 disableBmps = TRUE;
9612 disableImps = TRUE;
9613 }
9614
9615 if(TRUE == disableImps)
9616 {
9617 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9618 {
9619 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9620 }
9621 }
9622
9623 if(TRUE == disableBmps)
9624 {
9625 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9626 {
9627 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9628
9629 if(eHAL_STATUS_SUCCESS != halStatus)
9630 {
9631 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009632 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 VOS_ASSERT(0);
9634 return status;
9635 }
9636 }
9637
9638 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9639 {
9640 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9641
9642 if(eHAL_STATUS_SUCCESS != halStatus)
9643 {
9644 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 VOS_ASSERT(0);
9647 return status;
9648 }
9649 }
9650 }
9651
9652 if((TRUE == disableBmps) ||
9653 (TRUE == disableImps))
9654 {
9655 /* Now, get the chip into Full Power now */
9656 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9657 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9658 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9659
9660 if(halStatus != eHAL_STATUS_SUCCESS)
9661 {
9662 if(halStatus == eHAL_STATUS_PMC_PENDING)
9663 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309664 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309666 ret = wait_for_completion_interruptible_timeout(
9667 &pHddCtx->full_pwr_comp_var,
9668 msecs_to_jiffies(1000));
9669 if (ret <= 0)
9670 {
9671 hddLog(VOS_TRACE_LEVEL_ERROR,
9672 "%s: wait on full_pwr_comp_var failed %ld",
9673 __func__, ret);
9674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 }
9676 else
9677 {
9678 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009679 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 VOS_ASSERT(0);
9681 return status;
9682 }
9683 }
9684
9685 status = VOS_STATUS_SUCCESS;
9686 }
9687
9688 break;
9689 }
9690 return status;
9691}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309692
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309693void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309694{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309695 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309696
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309697 request = hdd_request_get(context);
9698 if (!request) {
9699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9700 return;
9701 }
9702
9703 hdd_request_complete(request);
9704 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309705}
9706
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309707
Katya Nigame7b69a82015-04-28 15:24:06 +05309708void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9709 {
9710 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309711
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309712 spin_lock_init(&pAdapter->sta_hash_lock);
9713 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9714
9715 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309716 pMonCtx->state = 0;
9717 pMonCtx->ChannelNo = 1;
9718 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309719 pMonCtx->crcCheckEnabled = 1;
9720 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9721 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309722 pMonCtx->numOfMacFilters = 0;
9723 }
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725
9726hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009727 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 tANI_U8 rtnl_held )
9729{
9730 hdd_adapter_t *pAdapter = NULL;
9731 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9732 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9733 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309734 v_CONTEXT_t pVosContext = NULL;
9735
9736 /* No need to check for NULL, reaching this step
9737 * means vos context is initialized
9738 */
9739 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
Arif Hussain6d2a3322013-11-17 19:50:10 -08009741 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009742
Nirav Shah436658f2014-02-28 17:05:45 +05309743 if(macAddr == NULL)
9744 {
9745 /* Not received valid macAddr */
9746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9747 "%s:Unable to add virtual intf: Not able to get"
9748 "valid mac address",__func__);
9749 return NULL;
9750 }
9751
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 //Disable BMPS incase of Concurrency
9753 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9754
9755 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9756 {
9757 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309758 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 VOS_ASSERT(0);
9760 return NULL;
9761 }
9762
9763 switch(session_type)
9764 {
9765 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009767 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 {
9769 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9770
9771 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309772 {
9773 hddLog(VOS_TRACE_LEVEL_FATAL,
9774 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009777
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309778#ifdef FEATURE_WLAN_TDLS
9779 /* A Mutex Lock is introduced while changing/initializing the mode to
9780 * protect the concurrent access for the Adapters by TDLS module.
9781 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309782 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309783#endif
9784
Jeff Johnsone7245742012-09-05 17:12:55 -07009785 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9786 NL80211_IFTYPE_P2P_CLIENT:
9787 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309790#ifdef FEATURE_WLAN_TDLS
9791 mutex_unlock(&pHddCtx->tdls_lock);
9792#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309793
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309794 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309795 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 if( VOS_STATUS_SUCCESS != status )
9797 goto err_free_netdev;
9798
9799 status = hdd_register_interface( pAdapter, rtnl_held );
9800 if( VOS_STATUS_SUCCESS != status )
9801 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309802#ifdef FEATURE_WLAN_TDLS
9803 mutex_lock(&pHddCtx->tdls_lock);
9804#endif
c_hpothu002231a2015-02-05 14:58:51 +05309805 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309806#ifdef FEATURE_WLAN_TDLS
9807 mutex_unlock(&pHddCtx->tdls_lock);
9808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 goto err_free_netdev;
9810 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309811
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309812 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309813 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309814
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309815#ifdef WLAN_NS_OFFLOAD
9816 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309817 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 netif_tx_disable(pAdapter->dev);
9822 //netif_tx_disable(pWlanDev);
9823 netif_carrier_off(pAdapter->dev);
9824
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309825 if (WLAN_HDD_P2P_CLIENT == session_type ||
9826 WLAN_HDD_P2P_DEVICE == session_type)
9827 {
9828 /* Initialize the work queue to defer the
9829 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309830 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309831 hdd_p2p_roc_work_queue);
9832 }
9833
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 break;
9835 }
9836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 case WLAN_HDD_SOFTAP:
9839 {
9840 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9841 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309842 {
9843 hddLog(VOS_TRACE_LEVEL_FATAL,
9844 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9849 NL80211_IFTYPE_AP:
9850 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 pAdapter->device_mode = session_type;
9852
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309853 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309854 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 if( VOS_STATUS_SUCCESS != status )
9856 goto err_free_netdev;
9857
Nirav Shah7e3c8132015-06-22 23:51:42 +05309858 status = hdd_sta_id_hash_attach(pAdapter);
9859 if (VOS_STATUS_SUCCESS != status)
9860 {
9861 hddLog(VOS_TRACE_LEVEL_FATAL,
9862 FL("failed to attach hash for session %d"), session_type);
9863 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9864 goto err_free_netdev;
9865 }
9866
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 status = hdd_register_hostapd( pAdapter, rtnl_held );
9868 if( VOS_STATUS_SUCCESS != status )
9869 {
c_hpothu002231a2015-02-05 14:58:51 +05309870 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 goto err_free_netdev;
9872 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309873 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 netif_tx_disable(pAdapter->dev);
9875 netif_carrier_off(pAdapter->dev);
9876
9877 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309878
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309879 // Workqueue which gets scheduled in IPv4 notification callback.
9880 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9881 hdd_ipv4_notifier_work_queue);
9882
9883#ifdef WLAN_NS_OFFLOAD
9884 // Workqueue which gets scheduled in IPv6 notification callback.
9885 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9886 hdd_ipv6_notifier_work_queue);
9887#endif
9888
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309889 if (WLAN_HDD_P2P_GO == session_type)
9890 {
9891 /* Initialize the work queue to
9892 * defer the back to back RoC request */
9893 INIT_DELAYED_WORK(&pAdapter->roc_work,
9894 hdd_p2p_roc_work_queue);
9895 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309896
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 break;
9898 }
9899 case WLAN_HDD_MONITOR:
9900 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9902 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309903 {
9904 hddLog(VOS_TRACE_LEVEL_FATAL,
9905 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009908
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309909 pAdapter->device_mode = session_type;
9910 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9911
Katya Nigame7b69a82015-04-28 15:24:06 +05309912 // Register wireless extensions
9913 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9914 {
9915 hddLog(VOS_TRACE_LEVEL_FATAL,
9916 "hdd_register_wext() failed with status code %08d [x%08x]",
9917 status, status );
9918 status = VOS_STATUS_E_FAILURE;
9919 }
9920
Jeff Johnson295189b2012-06-20 16:38:30 -07009921#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9922 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9923#else
9924 pAdapter->dev->open = hdd_mon_open;
9925 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309926 pAdapter->dev->stop = hdd_mon_stop;
9927 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309929 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309930 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309932
9933 if (VOS_MONITOR_MODE != hdd_get_conparam())
9934 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9935
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309937 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309938 //Stop the Interface TX queue.
9939 netif_tx_disable(pAdapter->dev);
9940 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 }
9942 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 case WLAN_HDD_FTM:
9944 {
9945 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9946
9947 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309948 {
9949 hddLog(VOS_TRACE_LEVEL_FATAL,
9950 FL("failed to allocate adapter for session %d"), session_type);
9951 return NULL;
9952 }
9953
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9955 * message while loading driver in FTM mode. */
9956 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9957 pAdapter->device_mode = session_type;
9958 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309959
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309960 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309961 hdd_init_tx_rx( pAdapter );
9962
9963 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309965 netif_tx_disable(pAdapter->dev);
9966 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 }
9968 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 default:
9970 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309971 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9972 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 VOS_ASSERT(0);
9974 return NULL;
9975 }
9976 }
9977
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 if( VOS_STATUS_SUCCESS == status )
9979 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309980 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9982 if( NULL == pHddAdapterNode )
9983 {
9984 status = VOS_STATUS_E_NOMEM;
9985 }
9986 else
9987 {
9988 pHddAdapterNode->pAdapter = pAdapter;
9989 status = hdd_add_adapter_back ( pHddCtx,
9990 pHddAdapterNode );
9991 }
9992 }
9993
9994 if( VOS_STATUS_SUCCESS != status )
9995 {
9996 if( NULL != pAdapter )
9997 {
9998 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9999 pAdapter = NULL;
10000 }
10001 if( NULL != pHddAdapterNode )
10002 {
10003 vos_mem_free( pHddAdapterNode );
10004 }
10005
10006 goto resume_bmps;
10007 }
10008
10009 if(VOS_STATUS_SUCCESS == status)
10010 {
10011 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010012 //Initialize the WoWL service
10013 if(!hdd_init_wowl(pAdapter))
10014 {
10015 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10016 goto err_free_netdev;
10017 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010018 //Initialize the TSF capture data
10019 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 return pAdapter;
10022
10023err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 wlan_hdd_release_intf_addr( pHddCtx,
10025 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010026 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010027
10028resume_bmps:
10029 //If bmps disabled enable it
10030 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10031 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010032 if (pHddCtx->hdd_wlan_suspended)
10033 {
10034 hdd_set_pwrparams(pHddCtx);
10035 }
10036 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 }
10038 return NULL;
10039}
10040
10041VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10042 tANI_U8 rtnl_held )
10043{
10044 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10045 VOS_STATUS status;
10046
10047 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10048 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010049 {
10050 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10051 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010053 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010054
10055 while ( pCurrent->pAdapter != pAdapter )
10056 {
10057 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10058 if( VOS_STATUS_SUCCESS != status )
10059 break;
10060
10061 pCurrent = pNext;
10062 }
10063 pAdapterNode = pCurrent;
10064 if( VOS_STATUS_SUCCESS == status )
10065 {
10066 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10067 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010068
10069#ifdef FEATURE_WLAN_TDLS
10070
10071 /* A Mutex Lock is introduced while changing/initializing the mode to
10072 * protect the concurrent access for the Adapters by TDLS module.
10073 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010074 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010075#endif
10076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 hdd_remove_adapter( pHddCtx, pAdapterNode );
10078 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010079 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010080
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010081#ifdef FEATURE_WLAN_TDLS
10082 mutex_unlock(&pHddCtx->tdls_lock);
10083#endif
10084
Jeff Johnson295189b2012-06-20 16:38:30 -070010085
10086 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010087 if ((!vos_concurrent_open_sessions_running()) &&
10088 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10089 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010091 if (pHddCtx->hdd_wlan_suspended)
10092 {
10093 hdd_set_pwrparams(pHddCtx);
10094 }
10095 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 }
10097
10098 return VOS_STATUS_SUCCESS;
10099 }
10100
10101 return VOS_STATUS_E_FAILURE;
10102}
10103
10104VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10105{
10106 hdd_adapter_list_node_t *pHddAdapterNode;
10107 VOS_STATUS status;
10108
10109 ENTER();
10110
10111 do
10112 {
10113 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10114 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10115 {
10116 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10117 vos_mem_free( pHddAdapterNode );
10118 }
10119 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10120
10121 EXIT();
10122
10123 return VOS_STATUS_SUCCESS;
10124}
10125
10126void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10127{
10128 v_U8_t addIE[1] = {0};
10129
10130 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10131 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10132 eANI_BOOLEAN_FALSE) )
10133 {
10134 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010135 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 }
10137
10138 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10139 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10140 eANI_BOOLEAN_FALSE) )
10141 {
10142 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010143 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 }
10145
10146 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10147 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10148 eANI_BOOLEAN_FALSE) )
10149 {
10150 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010151 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 }
10153}
10154
Anurag Chouhan83026002016-12-13 22:46:21 +053010155VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10156{
10157#ifdef DHCP_SERVER_OFFLOAD
10158 vos_event_destroy(&adapter->dhcp_status.vos_event);
10159#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010160#ifdef MDNS_OFFLOAD
10161 vos_event_destroy(&adapter->mdns_status.vos_event);
10162#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010163 return VOS_STATUS_SUCCESS;
10164}
10165
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010166int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10167{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010168 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010169 hdd_mon_ctx_t *mon_ctx;
10170 void (*func_ptr)(void *context) = NULL;
10171 int ret = 0;
10172 void *cookie = NULL;
10173 struct hdd_request *request;
10174 static const struct hdd_request_params params = {
10175 .priv_size = 0,
10176 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10177 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010178
10179 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10180 if (!adapter) {
10181 hddLog(LOGE, FL("Invalid STA + MON mode"));
10182 return -EINVAL;
10183 }
10184
10185 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10186 if (!mon_ctx)
10187 return 0;
10188
10189 if (mon_ctx->state != MON_MODE_START)
10190 return 0;
10191
10192 mon_ctx->state = MON_MODE_STOP;
10193 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010194 func_ptr = hdd_mon_post_msg_cb;
10195 request = hdd_request_alloc(&params);
10196 if (!request) {
10197 hddLog(VOS_TRACE_LEVEL_ERROR,
10198 FL("Request allocation failure"));
10199 return -ENOMEM;
10200 }
10201 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010202 }
10203
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010204 /*
10205 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10206 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10207 * and so uninitialized cookie won't be accessed.
10208 */
10209 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010210 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010211 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010212 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010213 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010214 }
10215
10216 if (!wait)
10217 goto bmps_roaming;
10218
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010219 if (!ret)
10220 ret = hdd_request_wait_for_response(request);
10221 hdd_request_put(request);
10222 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010223 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010224 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010225 return -EINVAL;
10226 }
10227
10228bmps_roaming:
10229 hddLog(LOG1, FL("Enable BMPS"));
10230 hdd_enable_bmps_imps(hdd_ctx);
10231 hdd_restore_roaming(hdd_ctx);
10232
10233 return 0;
10234}
10235
10236bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10237{
10238 hdd_adapter_t *mon_adapter;
10239 hdd_mon_ctx_t *mon_ctx;
10240
10241 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10242 return false;
10243
10244 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10245 if (!mon_adapter) {
10246 hddLog(LOGE, FL("Invalid concurrency mode"));
10247 return false;
10248 }
10249
10250 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10251 if (mon_ctx->state == MON_MODE_START)
10252 return true;
10253
10254 return false;
10255}
10256
10257int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10258{
10259 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10260
10261 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10262 !wlan_hdd_check_monitor_state(hdd_ctx))
10263 return 0;
10264
10265 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10266 return -EINVAL;
10267
10268 return 0;
10269}
10270
10271void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10272{
10273 if (!hdd_ctx)
10274 return;
10275
10276 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10277 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10278 return;
10279 }
10280
10281 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10282
10283 hdd_ctx->roaming_ini_original =
10284 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10285
10286 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10287 CFG_LFR_FEATURE_ENABLED_MIN;
10288
10289 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10290 CFG_LFR_FEATURE_ENABLED_MIN);
10291}
10292
10293void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10294{
10295 if (!hdd_ctx->roaming_ini_original)
10296 return;
10297
10298 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10299
10300 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10301 CFG_LFR_FEATURE_ENABLED_MAX;
10302
10303 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10304
10305 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10306 CFG_LFR_FEATURE_ENABLED_MAX);
10307}
Anurag Chouhan83026002016-12-13 22:46:21 +053010308
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010309VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10310 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010311{
10312 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10313 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010314 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010316 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010317 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010318 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010319
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010320 if (pHddCtx->isLogpInProgress) {
10321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10322 "%s:LOGP in Progress. Ignore!!!",__func__);
10323 return VOS_STATUS_E_FAILURE;
10324 }
10325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010327
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010328 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 switch(pAdapter->device_mode)
10330 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010331 case WLAN_HDD_IBSS:
10332 if ( VOS_TRUE == bCloseSession )
10333 {
10334 status = hdd_sta_id_hash_detach(pAdapter);
10335 if (status != VOS_STATUS_SUCCESS)
10336 hddLog(VOS_TRACE_LEVEL_ERROR,
10337 FL("sta id hash detach failed"));
10338 }
10339
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 case WLAN_HDD_INFRA_STATION:
10341 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010342 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010343 {
10344 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010345#ifdef FEATURE_WLAN_TDLS
10346 mutex_lock(&pHddCtx->tdls_lock);
10347 wlan_hdd_tdls_exit(pAdapter, TRUE);
10348 mutex_unlock(&pHddCtx->tdls_lock);
10349#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010350 if(hdd_connIsConnected(pstation) ||
10351 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 {
10353 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010354 {
10355 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10357 pAdapter->sessionId,
10358 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010359 /* Success implies disconnect command got queued up successfully
10360 * Or cmd not queued as scan for SSID is in progress
10361 */
10362 if((eHAL_STATUS_SUCCESS == halStatus) ||
10363 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10364 {
10365 ret = wait_for_completion_timeout(
10366 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010368 if (ret <= 0 &&
10369 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10370 {
10371 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010372 "%s: wait on disconnect_comp_var failed %ld",
10373 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010374 }
10375 }
10376 else
10377 {
10378 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10379 __func__);
10380 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010381 }
10382 else
10383 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010384 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 }
10386 memset(&wrqu, '\0', sizeof(wrqu));
10387 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10388 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10389 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10390 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010391 else if(pstation->conn_info.connState ==
10392 eConnectionState_Disconnecting)
10393 {
10394 ret = wait_for_completion_interruptible_timeout(
10395 &pAdapter->disconnect_comp_var,
10396 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10397 if (ret <= 0)
10398 {
10399 hddLog(VOS_TRACE_LEVEL_ERROR,
10400 FL("wait on disconnect_comp_var failed %ld"), ret);
10401 }
10402 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010403 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010405 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010407 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10408 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010409 {
10410 while (pAdapter->is_roc_inprogress)
10411 {
10412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10413 "%s: ROC in progress for session %d!!!",
10414 __func__, pAdapter->sessionId);
10415 // waiting for ROC to expire
10416 msleep(500);
10417 /* In GO present case , if retry exceeds 3,
10418 it means something went wrong. */
10419 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10420 {
10421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10422 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010423 if (eHAL_STATUS_SUCCESS !=
10424 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10425 pAdapter->sessionId ))
10426 {
10427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10428 FL("Failed to Cancel Remain on Channel"));
10429 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010430 wait_for_completion_interruptible_timeout(
10431 &pAdapter->cancel_rem_on_chan_var,
10432 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10433 break;
10434 }
10435 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010436 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010437 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010438#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010439 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010440#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010441
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010442 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010443
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010444 /* It is possible that the caller of this function does not
10445 * wish to close the session
10446 */
10447 if (VOS_TRUE == bCloseSession &&
10448 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 {
10450 INIT_COMPLETION(pAdapter->session_close_comp_var);
10451 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010452 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10453 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010455 unsigned long ret;
10456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010459 &pAdapter->session_close_comp_var,
10460 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010461 if ( 0 >= ret)
10462 {
10463 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010464 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010465 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 }
10467 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 break;
10470
10471 case WLAN_HDD_SOFTAP:
10472 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010473 if ( VOS_TRUE == bCloseSession )
10474 {
10475 status = hdd_sta_id_hash_detach(pAdapter);
10476 if (status != VOS_STATUS_SUCCESS)
10477 hddLog(VOS_TRACE_LEVEL_ERROR,
10478 FL("sta id hash detach failed"));
10479 }
10480
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010482 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010483 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10484 while (pAdapter->is_roc_inprogress) {
10485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10486 "%s: ROC in progress for session %d!!!",
10487 __func__, pAdapter->sessionId);
10488 msleep(500);
10489 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10491 "%s: ROC completion is not received.!!!", __func__);
10492 WLANSAP_CancelRemainOnChannel(
10493 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10494 wait_for_completion_interruptible_timeout(
10495 &pAdapter->cancel_rem_on_chan_var,
10496 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10497 break;
10498 }
10499 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010500
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010501 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010502 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010503#ifdef SAP_AUTH_OFFLOAD
10504 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10505 hdd_set_sap_auth_offload(pAdapter, FALSE);
10506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 mutex_lock(&pHddCtx->sap_lock);
10508 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10509 {
10510 VOS_STATUS status;
10511 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010512 hdd_hostapd_state_t *pHostapdState =
10513 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010514
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010515 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 //Stop Bss.
10517 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10518 if (VOS_IS_STATUS_SUCCESS(status))
10519 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10521
10522 if (!VOS_IS_STATUS_SUCCESS(status))
10523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010524 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10525 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 }
10527 }
10528 else
10529 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010530 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 }
10532 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010533 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534
10535 if (eHAL_STATUS_FAILURE ==
10536 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10537 0, NULL, eANI_BOOLEAN_FALSE))
10538 {
10539 hddLog(LOGE,
10540 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010541 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 }
10543
10544 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10545 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10546 eANI_BOOLEAN_FALSE) )
10547 {
10548 hddLog(LOGE,
10549 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10550 }
10551
10552 // Reset WNI_CFG_PROBE_RSP Flags
10553 wlan_hdd_reset_prob_rspies(pAdapter);
10554 kfree(pAdapter->sessionCtx.ap.beacon);
10555 pAdapter->sessionCtx.ap.beacon = NULL;
10556 }
10557 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010558
10559#ifdef WLAN_NS_OFFLOAD
10560 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10561#endif
10562 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10563
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010565
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010567 if (VOS_MONITOR_MODE != hdd_get_conparam())
10568 wlan_hdd_stop_mon(pHddCtx, true);
10569 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010570
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 default:
10572 break;
10573 }
10574
10575 EXIT();
10576 return VOS_STATUS_SUCCESS;
10577}
10578
Kapil Gupta137ef892016-12-13 19:38:00 +053010579/**
10580 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10581 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10582 *
10583 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10584 * After that WLANSAP_StartBss start re-start process of SAP.
10585 *
10586 * Return: None
10587 */
10588static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10589{
10590 hdd_ap_ctx_t *pHddApCtx;
10591 hdd_hostapd_state_t *pHostapdState;
10592 VOS_STATUS vos_status;
10593 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010594#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010595 struct station_del_parameters delStaParams;
10596#endif
10597 tsap_Config_t *pConfig;
10598
10599 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10600 pConfig = &pHddApCtx->sapConfig;
10601
10602 mutex_lock(&pHddCtx->sap_lock);
10603 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010604#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010605 delStaParams.mac = NULL;
10606 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10607 delStaParams.reason_code = eCsrForcedDeauthSta;
10608 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10609 &delStaParams);
10610#else
10611 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10612 NULL);
10613#endif
10614 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10615
10616 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10617 vos_event_reset(&pHostapdState->vosEvent);
10618
10619 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10620 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10621 10000);
10622 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10623 hddLog(LOGE, FL("SAP Stop Failed"));
10624 goto end;
10625 }
10626 }
10627 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10628 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10629 hddLog(LOG1, FL("SAP Stop Success"));
10630
10631 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10632 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10633 goto end;
10634 }
10635
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010636 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010637 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10638 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10639 hddLog(LOGE, FL("SAP Start Bss fail"));
10640 goto end;
10641 }
10642
10643 hddLog(LOG1, FL("Waiting for SAP to start"));
10644 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10645 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10646 hddLog(LOGE, FL("SAP Start failed"));
10647 goto end;
10648 }
10649 hddLog(LOG1, FL("SAP Start Success"));
10650 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10651 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10652 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010653 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10655 vos_event_reset(&pHostapdState->vosEvent);
10656 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10657 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10658 10000);
10659 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10660 hddLog(LOGE, FL("SAP Stop Failed"));
10661 goto end;
10662 }
10663 }
10664 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010665 }
10666end:
10667 mutex_unlock(&pHddCtx->sap_lock);
10668 return;
10669}
10670
10671/**
10672 * __hdd_sap_restart_handle() - to handle restarting of SAP
10673 * @work: name of the work
10674 *
10675 * Purpose of this function is to trigger sap start. this function
10676 * will be called from workqueue.
10677 *
10678 * Return: void.
10679 */
10680static void __hdd_sap_restart_handle(struct work_struct *work)
10681{
10682 hdd_adapter_t *sap_adapter;
10683 hdd_context_t *hdd_ctx = container_of(work,
10684 hdd_context_t,
10685 sap_start_work);
10686 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10687 vos_ssr_unprotect(__func__);
10688 return;
10689 }
10690 sap_adapter = hdd_get_adapter(hdd_ctx,
10691 WLAN_HDD_SOFTAP);
10692 if (sap_adapter == NULL) {
10693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10694 FL("sap_adapter is NULL"));
10695 vos_ssr_unprotect(__func__);
10696 return;
10697 }
10698
10699 if (hdd_ctx->is_ch_avoid_in_progress) {
10700 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10701 wlan_hdd_restart_sap(sap_adapter);
10702 hdd_change_ch_avoidance_status(hdd_ctx, false);
10703 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010704 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10705 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010706}
10707
10708/**
10709 * hdd_sap_restart_handle() - to handle restarting of SAP
10710 * @work: name of the work
10711 *
10712 * Purpose of this function is to trigger sap start. this function
10713 * will be called from workqueue.
10714 *
10715 * Return: void.
10716 */
10717static void hdd_sap_restart_handle(struct work_struct *work)
10718{
10719 vos_ssr_protect(__func__);
10720 __hdd_sap_restart_handle(work);
10721 vos_ssr_unprotect(__func__);
10722}
10723
10724
Abhishek Singh78c691f2017-11-30 13:48:44 +053010725/**
10726 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10727 * @work: name of the work
10728 *
10729 * Purpose of this function is to force SCC using ECSA. This function
10730 * will be called from workqueue.
10731 *
10732 * Return: void.
10733 */
10734static void
10735__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10736{
10737 hdd_adapter_t *sap_adapter;
10738 hdd_station_ctx_t *sta_ctx;
10739 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010740 ptSapContext sap_ctx = NULL;
10741 v_CONTEXT_t vos_ctx;
10742 tANI_U8 target_channel;
10743 tsap_Config_t *sap_config;
10744 bool sta_sap_scc_on_dfs_chan;
10745 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010746 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10747 hdd_context_t,
10748 ecsa_chan_change_work);
10749
10750 if (wlan_hdd_validate_context(hdd_ctx))
10751 return;
10752
10753 sap_adapter = hdd_get_adapter(hdd_ctx,
10754 WLAN_HDD_SOFTAP);
10755 if (!sap_adapter) {
10756 hddLog(LOGE, FL("sap_adapter is NULL"));
10757 return;
10758 }
10759
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010760 vos_ctx = hdd_ctx->pvosContext;
10761 if (!vos_ctx) {
10762 hddLog(LOGE, FL("vos_ctx is NULL"));
10763 return;
10764 }
10765
10766 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10767 if (!sap_ctx) {
10768 hddLog(LOGE, FL("sap_ctx is NULL"));
10769 return;
10770 }
10771
10772 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10773
10774 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10775
Abhishek Singh78c691f2017-11-30 13:48:44 +053010776 sta_adapter = hdd_get_adapter(hdd_ctx,
10777 WLAN_HDD_INFRA_STATION);
10778 if (!sta_adapter) {
10779 hddLog(LOGE, FL("sta_adapter is NULL"));
10780 return;
10781 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010782
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010783 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010784 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010785 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10786
10787 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10788 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10789 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10790 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10791 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10792 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10793 chan_state);
10794 if (sta_sap_scc_on_dfs_chan &&
10795 (chan_state == NV_CHANNEL_DFS)) {
10796 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10797 target_channel = sap_config->user_config_channel;
10798 goto switch_channel;
10799 }
10800 }
10801 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010802 }
10803
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010804 target_channel = sta_ctx->conn_info.operationChannel;
10805switch_channel:
10806 hddLog(LOGE, FL("Switch SAP to %d channel"),
10807 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010808 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10809 return;
10810
10811abort:
10812 wlansap_reset_chan_change_in_progress(sap_ctx);
10813 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010814}
10815
10816/**
10817 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10818 * @work: name of the work
10819 *
10820 * Purpose of this function is to force SCC using ECSA. This function
10821 * will be called from workqueue.
10822 *
10823 * Return: void.
10824 */
10825static void
10826hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10827{
10828 vos_ssr_protect(__func__);
10829 __hdd_force_scc_with_ecsa_handle(work);
10830 vos_ssr_unprotect(__func__);
10831}
10832
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010833int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10834{
10835 int ret;
10836 ptSapContext sap_ctx = NULL;
10837 v_CONTEXT_t vos_ctx;
10838
10839 vos_ctx = hdd_ctx->pvosContext;
10840 if (!vos_ctx) {
10841 hddLog(LOGE, FL("vos_ctx is NULL"));
10842 return 0;
10843 }
10844
10845 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10846 if (!sap_ctx) {
10847 hddLog(LOG1, FL("sap_ctx is NULL"));
10848 return 0;
10849 }
10850 if(!sap_ctx->isSapSessionOpen) {
10851 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10852 sap_ctx->sapsMachine);
10853 return 0;
10854 }
10855
10856 if (!wlansap_get_change_in_progress(sap_ctx)) {
10857 hddLog(LOG1, FL("channel switch not in progress"));
10858 return 0;
10859 }
10860 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10861 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10862 if (!ret)
10863 {
10864 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10865 return ret;
10866 }
10867
10868 return 0;
10869}
10870
10871
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010872/**
10873 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10874 * dfs chan
10875 * @hdd_ctx: pointer to hdd context
10876 *
10877 * This function used to check if sta+sap scc allowed on DFS channel.
10878 *
10879 * Return: None
10880 */
10881bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10882{
10883 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10884 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10885 return true;
10886 else
10887 return false;
10888}
10889
Jeff Johnson295189b2012-06-20 16:38:30 -070010890VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10891{
10892 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10893 VOS_STATUS status;
10894 hdd_adapter_t *pAdapter;
10895
10896 ENTER();
10897
10898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10899
10900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10901 {
10902 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010903
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010904 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010905
10906 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10907 pAdapterNode = pNext;
10908 }
10909
10910 EXIT();
10911
10912 return VOS_STATUS_SUCCESS;
10913}
10914
Rajeev Kumarf999e582014-01-09 17:33:29 -080010915
10916#ifdef FEATURE_WLAN_BATCH_SCAN
10917/**---------------------------------------------------------------------------
10918
10919 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10920 structures
10921
10922 \param - pAdapter Pointer to HDD adapter
10923
10924 \return - None
10925
10926 --------------------------------------------------------------------------*/
10927void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10928{
10929 tHddBatchScanRsp *pNode;
10930 tHddBatchScanRsp *pPrev;
10931
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010932 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010933 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010934 hddLog(VOS_TRACE_LEVEL_ERROR,
10935 "%s: Adapter context is Null", __func__);
10936 return;
10937 }
10938
10939 pNode = pAdapter->pBatchScanRsp;
10940 while (pNode)
10941 {
10942 pPrev = pNode;
10943 pNode = pNode->pNext;
10944 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010945 }
10946
10947 pAdapter->pBatchScanRsp = NULL;
10948 pAdapter->numScanList = 0;
10949 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10950 pAdapter->prev_batch_id = 0;
10951
10952 return;
10953}
10954#endif
10955
10956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10958{
10959 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10960 VOS_STATUS status;
10961 hdd_adapter_t *pAdapter;
10962
10963 ENTER();
10964
10965 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10966
10967 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10968 {
10969 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010970 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010972
10973 if (pHddCtx->cfg_ini->sap_internal_restart &&
10974 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10975 hddLog(LOG1, FL("driver supports sap restart"));
10976 vos_flush_work(&pHddCtx->sap_start_work);
10977 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10978 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010979 hdd_softap_deinit_tx_rx(pAdapter, true);
10980 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010981 } else {
10982 netif_carrier_off(pAdapter->dev);
10983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010984
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010985 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010986
10987 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10988 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010989
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010991
Katya Nigam1fd24402015-02-16 14:52:19 +053010992 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10993 hdd_ibss_deinit_tx_rx(pAdapter);
10994
Nirav Shah7e3c8132015-06-22 23:51:42 +053010995 status = hdd_sta_id_hash_detach(pAdapter);
10996 if (status != VOS_STATUS_SUCCESS)
10997 hddLog(VOS_TRACE_LEVEL_ERROR,
10998 FL("sta id hash detach failed for session id %d"),
10999 pAdapter->sessionId);
11000
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011001 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11002
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011003 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11004 {
11005 hdd_wmm_adapter_close( pAdapter );
11006 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11007 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011008
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011009 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11010 {
11011 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11012 }
11013
Rajeev Kumarf999e582014-01-09 17:33:29 -080011014#ifdef FEATURE_WLAN_BATCH_SCAN
11015 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11016 {
11017 hdd_deinit_batch_scan(pAdapter);
11018 }
11019#endif
11020
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011021#ifdef FEATURE_WLAN_TDLS
11022 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011023 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011024 mutex_unlock(&pHddCtx->tdls_lock);
11025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11027 pAdapterNode = pNext;
11028 }
11029
11030 EXIT();
11031
11032 return VOS_STATUS_SUCCESS;
11033}
11034
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011035/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011036 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11037 * @wiphy: wiphy
11038 * @channel: channel of the BSS to find
11039 * @bssid: bssid of the BSS to find
11040 * @ssid: ssid of the BSS to find
11041 * @ssid_len: ssid len of of the BSS to find
11042 *
11043 * The API is a wrapper to get bss from kernel matching the chan,
11044 * bssid and ssid
11045 *
11046 * Return: Void
11047 */
11048#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11049 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11050
11051struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11052 struct ieee80211_channel *channel,
11053 const u8 *bssid,
11054 const u8 *ssid, size_t ssid_len)
11055{
11056 return cfg80211_get_bss(wiphy, channel, bssid,
11057 ssid, ssid_len,
11058 WLAN_CAPABILITY_ESS,
11059 WLAN_CAPABILITY_ESS);
11060}
11061#else
11062struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11063 struct ieee80211_channel *channel,
11064 const u8 *bssid,
11065 const u8 *ssid, size_t ssid_len)
11066{
11067 return cfg80211_get_bss(wiphy, channel, bssid,
11068 ssid, ssid_len,
11069 IEEE80211_BSS_TYPE_ESS,
11070 IEEE80211_PRIVACY_ANY);
11071}
11072#endif
11073
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011074#if defined(CFG80211_CONNECT_BSS) || \
11075 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11076
11077#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11078 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11079/**
11080 * hdd_connect_bss() - helper function to send connection status to supplicant
11081 * @dev: network device
11082 * @bssid: bssid to which we want to associate
11083 * @bss: information about connected bss
11084 * @req_ie: Request Information Element
11085 * @req_ie_len: len of the req IE
11086 * @resp_ie: Response IE
11087 * @resp_ie_len: len of ht response IE
11088 * @status: status
11089 * @gfp: Kernel Flag
11090 *
11091 * This is a helper function to send connection status to supplicant
11092 * and gets invoked from wrapper API
11093 *
11094 * Return: Void
11095 */
11096static void hdd_connect_bss(struct net_device *dev,
11097 const u8 *bssid,
11098 struct cfg80211_bss *bss,
11099 const u8 *req_ie,
11100 size_t req_ie_len,
11101 const u8 *resp_ie,
11102 size_t resp_ie_len,
11103 u16 status,
11104 gfp_t gfp)
11105{
11106 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11107 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11108}
11109#else
11110/**
11111 * hdd_connect_bss() - helper function to send connection status to supplicant
11112 * @dev: network device
11113 * @bssid: bssid to which we want to associate
11114 * @bss: information about connected bss
11115 * @req_ie: Request Information Element
11116 * @req_ie_len: len of the req IE
11117 * @resp_ie: Response IE
11118 * @resp_ie_len: len of ht response IE
11119 * @status: status
11120 * @gfp: Kernel Flag
11121 *
11122 * This is a helper function to send connection status to supplicant
11123 * and gets invoked from wrapper API
11124 *
11125 * Return: Void
11126 */
11127static void hdd_connect_bss(struct net_device *dev,
11128 const u8 *bssid,
11129 struct cfg80211_bss *bss,
11130 const u8 *req_ie,
11131 size_t req_ie_len,
11132 const u8 *resp_ie,
11133 size_t resp_ie_len,
11134 u16 status,
11135 gfp_t gfp)
11136{
11137 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11138 resp_ie, resp_ie_len, status, gfp);
11139}
11140#endif
11141
Abhishek Singh5a597e62016-12-05 15:16:30 +053011142/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011143 * hdd_connect_result() - API to send connection status to supplicant
11144 * @dev: network device
11145 * @bssid: bssid to which we want to associate
11146 * @roam_info: information about connected bss
11147 * @req_ie: Request Information Element
11148 * @req_ie_len: len of the req IE
11149 * @resp_ie: Response IE
11150 * @resp_ie_len: len of ht response IE
11151 * @status: status
11152 * @gfp: Kernel Flag
11153 *
11154 * The API is a wrapper to send connection status to supplicant
11155 *
11156 * Return: Void
11157 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011158void hdd_connect_result(struct net_device *dev,
11159 const u8 *bssid,
11160 tCsrRoamInfo *roam_info,
11161 const u8 *req_ie,
11162 size_t req_ie_len,
11163 const u8 *resp_ie,
11164 size_t resp_ie_len,
11165 u16 status,
11166 gfp_t gfp)
11167{
11168 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11169 struct cfg80211_bss *bss = NULL;
11170
11171 if (WLAN_STATUS_SUCCESS == status) {
11172 struct ieee80211_channel *chan;
11173 int freq;
11174 int chan_no = roam_info->pBssDesc->channelId;;
11175
11176 if (chan_no <= 14)
11177 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011178 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011179 else
11180 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011181 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011182
11183 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011184 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11185 chan, bssid,
11186 roam_info->u.pConnectedProfile->SSID.ssId,
11187 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011188 }
11189
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011190 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11191 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011192}
11193#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011194/**
11195 * hdd_connect_result() - API to send connection status to supplicant
11196 * @dev: network device
11197 * @bssid: bssid to which we want to associate
11198 * @roam_info: information about connected bss
11199 * @req_ie: Request Information Element
11200 * @req_ie_len: len of the req IE
11201 * @resp_ie: Response IE
11202 * @resp_ie_len: len of ht response IE
11203 * @status: status
11204 * @gfp: Kernel Flag
11205 *
11206 * The API is a wrapper to send connection status to supplicant
11207 *
11208 * Return: Void
11209 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011210void hdd_connect_result(struct net_device *dev,
11211 const u8 *bssid,
11212 tCsrRoamInfo *roam_info,
11213 const u8 *req_ie,
11214 size_t req_ie_len,
11215 const u8 * resp_ie,
11216 size_t resp_ie_len,
11217 u16 status,
11218 gfp_t gfp)
11219{
11220 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11221 resp_ie, resp_ie_len, status, gfp);
11222}
11223#endif
11224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11226{
11227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11228 VOS_STATUS status;
11229 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011230 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011231 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
11233 ENTER();
11234
11235 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11236
11237 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11238 {
11239 pAdapter = pAdapterNode->pAdapter;
11240
Kumar Anand82c009f2014-05-29 00:29:42 -070011241 hdd_wmm_init( pAdapter );
11242
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 switch(pAdapter->device_mode)
11244 {
11245 case WLAN_HDD_INFRA_STATION:
11246 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011247 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011248
11249 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 hdd_init_station_mode(pAdapter);
11252 /* Open the gates for HDD to receive Wext commands */
11253 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011254 pHddCtx->scan_info.mScanPending = FALSE;
11255 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011258 if (!pHddCtx->isLogpInProgress)
11259 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011260
11261 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011262 if (eConnectionState_Associated == connState ||
11263 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
11265 union iwreq_data wrqu;
11266 memset(&wrqu, '\0', sizeof(wrqu));
11267 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11268 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11269 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011270 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011273 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011274 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011276 else if (eConnectionState_Connecting == connState)
11277 {
11278 /*
11279 * Indicate connect failure to supplicant if we were in the
11280 * process of connecting
11281 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011282 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011283 NULL, 0, NULL, 0,
11284 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11285 GFP_KERNEL);
11286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 break;
11288
11289 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011290 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011291 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011292 status = hdd_sta_id_hash_attach(pAdapter);
11293 if (VOS_STATUS_SUCCESS != status)
11294 {
11295 hddLog(VOS_TRACE_LEVEL_FATAL,
11296 FL("failed to attach hash for"));
11297 }
11298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 break;
11300
11301 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011304 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 break;
11306
11307 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011308 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11309
11310 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11311 if (!pVosContext) {
11312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11313 break;
11314 }
11315
11316 hdd_init_tx_rx(pAdapter);
11317 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011319
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 default:
11321 break;
11322 }
11323
11324 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11325 pAdapterNode = pNext;
11326 }
11327
11328 EXIT();
11329
11330 return VOS_STATUS_SUCCESS;
11331}
11332
11333VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11334{
11335 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11336 hdd_adapter_t *pAdapter;
11337 VOS_STATUS status;
11338 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011339 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
11341 ENTER();
11342
11343 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11344
11345 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11346 {
11347 pAdapter = pAdapterNode->pAdapter;
11348
11349 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11350 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11351 {
11352 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11353 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11354
Abhishek Singhf4669da2014-05-26 15:07:49 +053011355 hddLog(VOS_TRACE_LEVEL_INFO,
11356 "%s: Set HDD connState to eConnectionState_NotConnected",
11357 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011358 spin_lock_bh(&pAdapter->lock_for_active_session);
11359 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11360 {
11361 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011364 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 init_completion(&pAdapter->disconnect_comp_var);
11366 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11367 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11368
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011369 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011370 &pAdapter->disconnect_comp_var,
11371 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011372 if (0 >= ret)
11373 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11374 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011375
11376 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11377 pHddCtx->isAmpAllowed = VOS_FALSE;
11378 sme_RoamConnect(pHddCtx->hHal,
11379 pAdapter->sessionId, &(pWextState->roamProfile),
11380 &roamId);
11381 }
11382
11383 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11384 pAdapterNode = pNext;
11385 }
11386
11387 EXIT();
11388
11389 return VOS_STATUS_SUCCESS;
11390}
11391
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011392void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11393{
11394 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11395 VOS_STATUS status;
11396 hdd_adapter_t *pAdapter;
11397 hdd_station_ctx_t *pHddStaCtx;
11398 hdd_ap_ctx_t *pHddApCtx;
11399 hdd_hostapd_state_t * pHostapdState;
11400 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11401 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11402 const char *p2pMode = "DEV";
11403 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011404
11405 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11406 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11407 {
11408 pAdapter = pAdapterNode->pAdapter;
11409 switch (pAdapter->device_mode) {
11410 case WLAN_HDD_INFRA_STATION:
11411 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11412 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11413 staChannel = pHddStaCtx->conn_info.operationChannel;
11414 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11415 }
11416 break;
11417 case WLAN_HDD_P2P_CLIENT:
11418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11419 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11420 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11421 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11422 p2pMode = "CLI";
11423 }
11424 break;
11425 case WLAN_HDD_P2P_GO:
11426 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11427 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11428 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11429 p2pChannel = pHddApCtx->operatingChannel;
11430 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11431 }
11432 p2pMode = "GO";
11433 break;
11434 case WLAN_HDD_SOFTAP:
11435 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11436 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11437 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11438 apChannel = pHddApCtx->operatingChannel;
11439 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11440 }
11441 break;
11442 default:
11443 break;
11444 }
11445 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11446 pAdapterNode = pNext;
11447 }
11448 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11449 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11450 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011451 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11452 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011453 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011454 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011455 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11456 }
11457 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011458 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011459 apChannel, MAC_ADDR_ARRAY(apBssid));
11460 }
11461
11462 if (p2pChannel > 0 && apChannel > 0) {
11463 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11464 }
11465}
11466
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011467bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011468{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011469 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011470}
11471
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011472/* Once SSR is disabled then it cannot be set. */
11473void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011474{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011475 if (HDD_SSR_DISABLED == isSsrRequired)
11476 return;
11477
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 isSsrRequired = value;
11479}
11480
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011481void hdd_set_pre_close( hdd_context_t *pHddCtx)
11482{
11483 sme_PreClose(pHddCtx->hHal);
11484}
11485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11487 hdd_adapter_list_node_t** ppAdapterNode)
11488{
11489 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011490 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11492 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011493 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 return status;
11495}
11496
11497VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11498 hdd_adapter_list_node_t* pAdapterNode,
11499 hdd_adapter_list_node_t** pNextAdapterNode)
11500{
11501 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011502 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11504 (hdd_list_node_t*) pAdapterNode,
11505 (hdd_list_node_t**)pNextAdapterNode );
11506
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011507 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 return status;
11509}
11510
11511VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11512 hdd_adapter_list_node_t* pAdapterNode)
11513{
11514 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011515 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11517 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011518 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 return status;
11520}
11521
11522VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11523 hdd_adapter_list_node_t** ppAdapterNode)
11524{
11525 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011526 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011527 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11528 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011529 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 return status;
11531}
11532
11533VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11534 hdd_adapter_list_node_t* pAdapterNode)
11535{
11536 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011537 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11539 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011540 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 return status;
11542}
11543
11544VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11545 hdd_adapter_list_node_t* pAdapterNode)
11546{
11547 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011548 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11550 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011551 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 return status;
11553}
11554
11555hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11556 tSirMacAddr macAddr )
11557{
11558 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11559 hdd_adapter_t *pAdapter;
11560 VOS_STATUS status;
11561
11562 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11563
11564 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11565 {
11566 pAdapter = pAdapterNode->pAdapter;
11567
11568 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11569 macAddr, sizeof(tSirMacAddr) ) )
11570 {
11571 return pAdapter;
11572 }
11573 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11574 pAdapterNode = pNext;
11575 }
11576
11577 return NULL;
11578
11579}
11580
11581hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11582{
11583 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11584 hdd_adapter_t *pAdapter;
11585 VOS_STATUS status;
11586
11587 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11588
11589 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11590 {
11591 pAdapter = pAdapterNode->pAdapter;
11592
11593 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11594 IFNAMSIZ ) )
11595 {
11596 return pAdapter;
11597 }
11598 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11599 pAdapterNode = pNext;
11600 }
11601
11602 return NULL;
11603
11604}
11605
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011606hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11607 tANI_U32 sme_session_id )
11608{
11609 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11610 hdd_adapter_t *pAdapter;
11611 VOS_STATUS vos_status;
11612
11613
11614 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11615
11616 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11617 {
11618 pAdapter = pAdapterNode->pAdapter;
11619
11620 if (pAdapter->sessionId == sme_session_id)
11621 return pAdapter;
11622
11623 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11624 pAdapterNode = pNext;
11625 }
11626
11627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11628 "%s: sme_session_id %d does not exist with host",
11629 __func__, sme_session_id);
11630
11631 return NULL;
11632}
11633
Jeff Johnson295189b2012-06-20 16:38:30 -070011634hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11635{
11636 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11637 hdd_adapter_t *pAdapter;
11638 VOS_STATUS status;
11639
11640 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11641
11642 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11643 {
11644 pAdapter = pAdapterNode->pAdapter;
11645
11646 if( pAdapter && (mode == pAdapter->device_mode) )
11647 {
11648 return pAdapter;
11649 }
11650 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11651 pAdapterNode = pNext;
11652 }
11653
11654 return NULL;
11655
11656}
11657
11658//Remove this function later
11659hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11660{
11661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11662 hdd_adapter_t *pAdapter;
11663 VOS_STATUS status;
11664
11665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11666
11667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11668 {
11669 pAdapter = pAdapterNode->pAdapter;
11670
11671 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11672 {
11673 return pAdapter;
11674 }
11675
11676 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11677 pAdapterNode = pNext;
11678 }
11679
11680 return NULL;
11681
11682}
11683
Jeff Johnson295189b2012-06-20 16:38:30 -070011684/**---------------------------------------------------------------------------
11685
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011686 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011687
11688 This API returns the operating channel of the requested device mode
11689
11690 \param - pHddCtx - Pointer to the HDD context.
11691 - mode - Device mode for which operating channel is required
11692 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11693 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11694 \return - channel number. "0" id the requested device is not found OR it is not connected.
11695 --------------------------------------------------------------------------*/
11696v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11697{
11698 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11699 VOS_STATUS status;
11700 hdd_adapter_t *pAdapter;
11701 v_U8_t operatingChannel = 0;
11702
11703 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11704
11705 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11706 {
11707 pAdapter = pAdapterNode->pAdapter;
11708
11709 if( mode == pAdapter->device_mode )
11710 {
11711 switch(pAdapter->device_mode)
11712 {
11713 case WLAN_HDD_INFRA_STATION:
11714 case WLAN_HDD_P2P_CLIENT:
11715 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11716 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11717 break;
11718 case WLAN_HDD_SOFTAP:
11719 case WLAN_HDD_P2P_GO:
11720 /*softap connection info */
11721 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11722 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11723 break;
11724 default:
11725 break;
11726 }
11727
11728 break; //Found the device of interest. break the loop
11729 }
11730
11731 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11732 pAdapterNode = pNext;
11733 }
11734 return operatingChannel;
11735}
11736
11737#ifdef WLAN_FEATURE_PACKET_FILTERING
11738/**---------------------------------------------------------------------------
11739
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011740 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011741
11742 This used to set the multicast address list.
11743
11744 \param - dev - Pointer to the WLAN device.
11745 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011746 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011747
11748 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011749static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011750{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011751 hdd_adapter_t *pAdapter;
11752 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011754 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011756
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011757 ENTER();
11758
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011759 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011760 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 {
11762 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011763 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 return;
11765 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11767 ret = wlan_hdd_validate_context(pHddCtx);
11768 if (0 != ret)
11769 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011770 return;
11771 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 if (dev->flags & IFF_ALLMULTI)
11773 {
11774 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011775 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011776 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011778 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 {
11780 mc_count = netdev_mc_count(dev);
11781 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011782 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11784 {
11785 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011786 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011787 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 return;
11789 }
11790
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011791 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011792
11793 netdev_for_each_mc_addr(ha, dev) {
11794 if (i == mc_count)
11795 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011796 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11797 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011799 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011800 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 i++;
11802 }
11803 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011804
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011805 if (pHddCtx->hdd_wlan_suspended)
11806 {
11807 /*
11808 * Configure the Mcast address list to FW
11809 * If wlan is already in suspend mode
11810 */
11811 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11812 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011813 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 return;
11815}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011816
11817static void hdd_set_multicast_list(struct net_device *dev)
11818{
11819 vos_ssr_protect(__func__);
11820 __hdd_set_multicast_list(dev);
11821 vos_ssr_unprotect(__func__);
11822}
Jeff Johnson295189b2012-06-20 16:38:30 -070011823#endif
11824
11825/**---------------------------------------------------------------------------
11826
11827 \brief hdd_select_queue() -
11828
11829 This function is registered with the Linux OS for network
11830 core to decide which queue to use first.
11831
11832 \param - dev - Pointer to the WLAN device.
11833 - skb - Pointer to OS packet (sk_buff).
11834 \return - ac, Queue Index/access category corresponding to UP in IP header
11835
11836 --------------------------------------------------------------------------*/
11837v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011838 struct sk_buff *skb
11839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11840 , void *accel_priv
11841#endif
11842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11843 , select_queue_fallback_t fallback
11844#endif
11845)
Jeff Johnson295189b2012-06-20 16:38:30 -070011846{
11847 return hdd_wmm_select_queue(dev, skb);
11848}
11849
11850
11851/**---------------------------------------------------------------------------
11852
11853 \brief hdd_wlan_initial_scan() -
11854
11855 This function triggers the initial scan
11856
11857 \param - pAdapter - Pointer to the HDD adapter.
11858
11859 --------------------------------------------------------------------------*/
11860void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11861{
11862 tCsrScanRequest scanReq;
11863 tCsrChannelInfo channelInfo;
11864 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011865 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11867
11868 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11869 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11870 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11871
11872 if(sme_Is11dSupported(pHddCtx->hHal))
11873 {
11874 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11875 if ( HAL_STATUS_SUCCESS( halStatus ) )
11876 {
11877 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11878 if( !scanReq.ChannelInfo.ChannelList )
11879 {
11880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11881 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011882 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 return;
11884 }
11885 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11886 channelInfo.numOfChannels);
11887 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11888 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011889 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 }
11891
11892 scanReq.scanType = eSIR_PASSIVE_SCAN;
11893 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11894 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11895 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11896 }
11897 else
11898 {
11899 scanReq.scanType = eSIR_ACTIVE_SCAN;
11900 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11901 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11902 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11903 }
11904
11905 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11906 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11907 {
11908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11909 __func__, halStatus );
11910 }
11911
11912 if(sme_Is11dSupported(pHddCtx->hHal))
11913 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11914}
11915
Jeff Johnson295189b2012-06-20 16:38:30 -070011916/**---------------------------------------------------------------------------
11917
11918 \brief hdd_full_power_callback() - HDD full power callback function
11919
11920 This is the function invoked by SME to inform the result of a full power
11921 request issued by HDD
11922
11923 \param - callbackcontext - Pointer to cookie
11924 \param - status - result of request
11925
11926 \return - None
11927
11928 --------------------------------------------------------------------------*/
11929static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11930{
Jeff Johnson72a40512013-12-19 10:14:15 -080011931 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011932
11933 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011934 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
11936 if (NULL == callbackContext)
11937 {
11938 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011939 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011940 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 return;
11942 }
11943
Jeff Johnson72a40512013-12-19 10:14:15 -080011944 /* there is a race condition that exists between this callback
11945 function and the caller since the caller could time out either
11946 before or while this code is executing. we use a spinlock to
11947 serialize these actions */
11948 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011949
11950 if (POWER_CONTEXT_MAGIC != pContext->magic)
11951 {
11952 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011953 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 hddLog(VOS_TRACE_LEVEL_WARN,
11955 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011956 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 return;
11958 }
11959
Jeff Johnson72a40512013-12-19 10:14:15 -080011960 /* context is valid so caller is still waiting */
11961
11962 /* paranoia: invalidate the magic */
11963 pContext->magic = 0;
11964
11965 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011967
11968 /* serialization is complete */
11969 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011970}
11971
Katya Nigamf0511f62015-05-05 16:40:57 +053011972void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11973{
11974 pMonCtx->typeSubtypeBitmap = 0;
11975 if( type%10 ) /* Management Packets */
11976 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11977 type/=10;
11978 if( type%10 ) /* Control Packets */
11979 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11980 type/=10;
11981 if( type%10 ) /* Data Packets */
11982 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11983}
11984
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011985VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11986 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011987{
11988 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011989 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011990
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011991 if (MON_MODE_START == pMonCtx->state)
11992 monMsg.type = WDA_MON_START_REQ;
11993 else if (MON_MODE_STOP == pMonCtx->state)
11994 monMsg.type = WDA_MON_STOP_REQ;
11995 else {
11996 hddLog(VOS_TRACE_LEVEL_ERROR,
11997 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011998 return VOS_STATUS_E_FAILURE;
11999 }
12000
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012001 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12002 if (pMonModeReq == NULL) {
12003 hddLog(VOS_TRACE_LEVEL_ERROR,
12004 FL("fail to allocate memory for monitor mode req"));
12005 return VOS_STATUS_E_FAILURE;
12006 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012007
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012008 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012009 pMonModeReq->data = pMonCtx;
12010 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012011
Katya Nigamf0511f62015-05-05 16:40:57 +053012012 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012013 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012014 monMsg.bodyval = 0;
12015
12016 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12017 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12018 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012019 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012020 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012021 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012022}
12023
Katya Nigame7b69a82015-04-28 15:24:06 +053012024void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12025{
12026 VOS_STATUS vosStatus;
12027 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012028 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012029 int ret;
12030 void *cookie;
12031 struct hdd_request *request;
12032 static const struct hdd_request_params params = {
12033 .priv_size = 0,
12034 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12035 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012036
Katya Nigame7b69a82015-04-28 15:24:06 +053012037 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12038 if(pAdapter == NULL || pVosContext == NULL)
12039 {
12040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12041 return ;
12042 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012043
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012044 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12045 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12046 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012047 request = hdd_request_alloc(&params);
12048 if (!request) {
12049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12050 return;
12051 }
12052 cookie = hdd_request_cookie(request);
12053
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012054 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012055 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12056 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12058 FL("failed to post MON MODE REQ"));
12059 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012060 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012061 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012062
12063 ret = hdd_request_wait_for_response(request);
12064 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012066 FL("timeout on monitor mode completion %d"), ret);
12067
12068req_put:
12069 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012070 }
12071
Katya Nigame7b69a82015-04-28 15:24:06 +053012072 hdd_UnregisterWext(pAdapter->dev);
12073
12074 vos_mon_stop( pVosContext );
12075
12076 vosStatus = vos_sched_close( pVosContext );
12077 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12078 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12079 "%s: Failed to close VOSS Scheduler",__func__);
12080 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12081 }
12082
12083 vosStatus = vos_nv_close();
12084 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12085 {
12086 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12087 "%s: Failed to close NV", __func__);
12088 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12089 }
12090
12091 vos_close(pVosContext);
12092
12093 #ifdef WLAN_KD_READY_NOTIFIER
12094 nl_srv_exit(pHddCtx->ptt_pid);
12095 #else
12096 nl_srv_exit();
12097 #endif
12098
Katya Nigame7b69a82015-04-28 15:24:06 +053012099 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012100}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012101/**
12102 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12103 * @ wiphy: the wiphy to validate against
12104 *
12105 * Return: void
12106 */
12107void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12108{
12109 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012110 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012111 {
12112 if (NULL != wiphy->bands[i] &&
12113 (NULL != wiphy->bands[i]->channels))
12114 {
12115 vos_mem_free(wiphy->bands[i]->channels);
12116 wiphy->bands[i]->channels = NULL;
12117 }
12118 }
12119}
Jeff Johnson295189b2012-06-20 16:38:30 -070012120/**---------------------------------------------------------------------------
12121
12122 \brief hdd_wlan_exit() - HDD WLAN exit function
12123
12124 This is the driver exit point (invoked during rmmod)
12125
12126 \param - pHddCtx - Pointer to the HDD Context
12127
12128 \return - None
12129
12130 --------------------------------------------------------------------------*/
12131void hdd_wlan_exit(hdd_context_t *pHddCtx)
12132{
12133 eHalStatus halStatus;
12134 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12135 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012136 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012137 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012138 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012140 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012141
12142 ENTER();
12143
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012144
Katya Nigame7b69a82015-04-28 15:24:06 +053012145 if (VOS_MONITOR_MODE == hdd_get_conparam())
12146 {
12147 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12148 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012149 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012150 }
12151 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012152 {
12153 // Unloading, restart logic is no more required.
12154 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012155
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012156#ifdef FEATURE_WLAN_TDLS
12157 /* At the time of driver unloading; if tdls connection is present;
12158 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12159 * wlan_hdd_tdls_find_peer always checks for valid context;
12160 * as load/unload in progress there can be a race condition.
12161 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12162 * when tdls state is enabled.
12163 * As soon as driver set load/unload flag; tdls flag also needs
12164 * to be disabled so that hdd_rx_packet_cbk won't call
12165 * wlan_hdd_tdls_find_peer.
12166 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012167 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12168 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012169#endif
12170
c_hpothu5ab05e92014-06-13 17:34:05 +053012171 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12172 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012174 pAdapter = pAdapterNode->pAdapter;
12175 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012177 /* Disable TX on the interface, after this hard_start_xmit() will
12178 * not be called on that interface
12179 */
12180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12181 netif_tx_disable(pAdapter->dev);
12182
12183 /* Mark the interface status as "down" for outside world */
12184 netif_carrier_off(pAdapter->dev);
12185
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012186 /* DeInit the adapter. This ensures that all data packets
12187 * are freed.
12188 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012189#ifdef FEATURE_WLAN_TDLS
12190 mutex_lock(&pHddCtx->tdls_lock);
12191#endif
c_hpothu002231a2015-02-05 14:58:51 +053012192 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012193#ifdef FEATURE_WLAN_TDLS
12194 mutex_unlock(&pHddCtx->tdls_lock);
12195#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012196 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12197
12198 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012199
c_hpothu5ab05e92014-06-13 17:34:05 +053012200 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012201 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12202 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012203 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012204 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12205 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12206 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12207
c_hpothu5ab05e92014-06-13 17:34:05 +053012208 hdd_UnregisterWext(pAdapter->dev);
12209 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012212 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12213 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 }
mukul sharmabab477d2015-06-11 17:14:55 +053012215
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012216 // Cancel any outstanding scan requests. We are about to close all
12217 // of our adapters, but an adapter structure is what SME passes back
12218 // to our callback function. Hence if there are any outstanding scan
12219 // requests then there is a race condition between when the adapter
12220 // is closed and when the callback is invoked.We try to resolve that
12221 // race condition here by canceling any outstanding scans before we
12222 // close the adapters.
12223 // Note that the scans may be cancelled in an asynchronous manner,
12224 // so ideally there needs to be some kind of synchronization. Rather
12225 // than introduce a new synchronization here, we will utilize the
12226 // fact that we are about to Request Full Power, and since that is
12227 // synchronized, the expectation is that by the time Request Full
12228 // Power has completed all scans will be cancelled.
12229 if (pHddCtx->scan_info.mScanPending)
12230 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012231 if(NULL != pAdapter)
12232 {
12233 hddLog(VOS_TRACE_LEVEL_INFO,
12234 FL("abort scan mode: %d sessionId: %d"),
12235 pAdapter->device_mode,
12236 pAdapter->sessionId);
12237 }
12238 hdd_abort_mac_scan(pHddCtx,
12239 pHddCtx->scan_info.sessionId,
12240 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012241 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012243 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012244 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012245 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012246 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12247 {
12248 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12250 "%s: in middle of FTM START", __func__);
12251 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12252 msecs_to_jiffies(20000));
12253 if(!lrc)
12254 {
12255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12256 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12257 }
12258 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012259 wlan_hdd_ftm_close(pHddCtx);
12260 goto free_hdd_ctx;
12261 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012262
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 /* DeRegister with platform driver as client for Suspend/Resume */
12264 vosStatus = hddDeregisterPmOps(pHddCtx);
12265 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12266 {
12267 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12268 VOS_ASSERT(0);
12269 }
12270
12271 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12272 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12273 {
12274 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12275 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012276
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012277 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012278 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12279 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012280 {
12281 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12282 }
12283
12284 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012285 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12286 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12287 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012288 {
12289 hddLog(VOS_TRACE_LEVEL_ERROR,
12290 "%s: Cannot deallocate Traffic monitor timer", __func__);
12291 }
12292
Bhargav Shahd0715912015-10-01 18:17:37 +053012293 if (VOS_TIMER_STATE_RUNNING ==
12294 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12295 vos_timer_stop(&pHddCtx->delack_timer);
12296 }
12297
12298 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12299 &pHddCtx->delack_timer))) {
12300 hddLog(VOS_TRACE_LEVEL_ERROR,
12301 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12302 }
12303
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012304 if (VOS_TIMER_STATE_RUNNING ==
12305 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12306 vos_timer_stop(&pHddCtx->tdls_source_timer);
12307 }
12308
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012309 vos_set_snoc_high_freq_voting(false);
12310
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012311 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12312
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 //Disable IMPS/BMPS as we do not want the device to enter any power
12314 //save mode during shutdown
12315 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12316 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12318
12319 //Ensure that device is in full power as we will touch H/W during vos_Stop
12320 init_completion(&powerContext.completion);
12321 powerContext.magic = POWER_CONTEXT_MAGIC;
12322
12323 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12324 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12325
12326 if (eHAL_STATUS_SUCCESS != halStatus)
12327 {
12328 if (eHAL_STATUS_PMC_PENDING == halStatus)
12329 {
12330 /* request was sent -- wait for the response */
12331 lrc = wait_for_completion_interruptible_timeout(
12332 &powerContext.completion,
12333 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 if (lrc <= 0)
12335 {
12336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012337 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 }
12339 }
12340 else
12341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR,
12343 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012344 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 /* continue -- need to clean up as much as possible */
12346 }
12347 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012348 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12349 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12350 {
12351 /* This will issue a dump command which will clean up
12352 BTQM queues and unblock MC thread */
12353 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12354 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012355
Jeff Johnson72a40512013-12-19 10:14:15 -080012356 /* either we never sent a request, we sent a request and received a
12357 response or we sent a request and timed out. if we never sent a
12358 request or if we sent a request and got a response, we want to
12359 clear the magic out of paranoia. if we timed out there is a
12360 race condition such that the callback function could be
12361 executing at the same time we are. of primary concern is if the
12362 callback function had already verified the "magic" but had not
12363 yet set the completion variable when a timeout occurred. we
12364 serialize these activities by invalidating the magic while
12365 holding a shared spinlock which will cause us to block if the
12366 callback is currently executing */
12367 spin_lock(&hdd_context_lock);
12368 powerContext.magic = 0;
12369 spin_unlock(&hdd_context_lock);
12370
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012371 /* If Device is shutdown, no point for SME to wait for responses
12372 from device. Pre Close SME */
12373 if(wcnss_device_is_shutdown())
12374 {
12375 sme_PreClose(pHddCtx->hHal);
12376 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012377 hdd_debugfs_exit(pHddCtx);
12378
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012379#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012380 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012381 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12382#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012383 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012384 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12385
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 // Unregister the Net Device Notifier
12387 unregister_netdevice_notifier(&hdd_netdev_notifier);
12388
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 hdd_stop_all_adapters( pHddCtx );
12390
Jeff Johnson295189b2012-06-20 16:38:30 -070012391#ifdef WLAN_BTAMP_FEATURE
12392 vosStatus = WLANBAP_Stop(pVosContext);
12393 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12394 {
12395 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12396 "%s: Failed to stop BAP",__func__);
12397 }
12398#endif //WLAN_BTAMP_FEATURE
12399
12400 //Stop all the modules
12401 vosStatus = vos_stop( pVosContext );
12402 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12403 {
12404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12405 "%s: Failed to stop VOSS",__func__);
12406 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012407 if (isSsrPanicOnFailure())
12408 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 }
12410
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012413
12414 //Close the scheduler before calling vos_close to make sure no thread is
12415 // scheduled after the each module close is called i.e after all the data
12416 // structures are freed.
12417 vosStatus = vos_sched_close( pVosContext );
12418 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12419 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12420 "%s: Failed to close VOSS Scheduler",__func__);
12421 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12422 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012423#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12424 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012425 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012426#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012427 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012428 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012430#ifdef CONFIG_ENABLE_LINUX_REG
12431 vosStatus = vos_nv_close();
12432 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12433 {
12434 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12435 "%s: Failed to close NV", __func__);
12436 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12437 }
12438#endif
12439
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 //Close VOSS
12441 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12442 vos_close(pVosContext);
12443
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 //Close Watchdog
12445 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12446 vos_watchdog_close(pVosContext);
12447
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012448 //Clean up HDD Nlink Service
12449 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012450
Manjeet Singh47ee8472016-04-11 11:57:18 +053012451 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012452 wlan_free_fwr_mem_dump_buffer();
12453 memdump_deinit();
12454
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012455#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012456 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012457 {
12458 wlan_logging_sock_deactivate_svc();
12459 }
12460#endif
12461
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012462#ifdef WLAN_KD_READY_NOTIFIER
12463 nl_srv_exit(pHddCtx->ptt_pid);
12464#else
12465 nl_srv_exit();
12466#endif /* WLAN_KD_READY_NOTIFIER */
12467
Abhishek Singh00b71972016-01-07 10:51:04 +053012468#ifdef WLAN_FEATURE_RMC
12469 hdd_close_cesium_nl_sock();
12470#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012471
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 hdd_close_all_adapters( pHddCtx );
12473
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012474 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012475 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012476 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012477
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012478free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 /* free the power on lock from platform driver */
12480 if (free_riva_power_on_lock("wlan"))
12481 {
12482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12483 __func__);
12484 }
12485
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012486 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12487 wlan_hdd_free_cache_channels(pHddCtx);
12488
c_hpothu78c7b602014-05-17 17:35:49 +053012489 //Free up dynamically allocated members inside HDD Adapter
12490 if (pHddCtx->cfg_ini)
12491 {
12492 kfree(pHddCtx->cfg_ini);
12493 pHddCtx->cfg_ini= NULL;
12494 }
12495
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012496 hdd_request_manager_deinit();
12497
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012498 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012499 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012500 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12501 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012502 {
12503 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012504 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 if (hdd_is_ssr_required())
12508 {
12509 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012510 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 msleep(5000);
12512 }
12513 hdd_set_ssr_required (VOS_FALSE);
12514}
12515
12516
12517/**---------------------------------------------------------------------------
12518
12519 \brief hdd_update_config_from_nv() - Function to update the contents of
12520 the running configuration with parameters taken from NV storage
12521
12522 \param - pHddCtx - Pointer to the HDD global context
12523
12524 \return - VOS_STATUS_SUCCESS if successful
12525
12526 --------------------------------------------------------------------------*/
12527static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12528{
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 v_BOOL_t itemIsValid = VOS_FALSE;
12530 VOS_STATUS status;
12531 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12532 v_U8_t macLoop;
12533
12534 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12535 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12536 if(status != VOS_STATUS_SUCCESS)
12537 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012538 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 return VOS_STATUS_E_FAILURE;
12540 }
12541
12542 if (itemIsValid == VOS_TRUE)
12543 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12546 VOS_MAX_CONCURRENCY_PERSONA);
12547 if(status != VOS_STATUS_SUCCESS)
12548 {
12549 /* Get MAC from NV fail, not update CFG info
12550 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012551 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 return VOS_STATUS_E_FAILURE;
12553 }
12554
12555 /* If first MAC is not valid, treat all others are not valid
12556 * Then all MACs will be got from ini file */
12557 if(vos_is_macaddr_zero(&macFromNV[0]))
12558 {
12559 /* MAC address in NV file is not configured yet */
12560 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12561 return VOS_STATUS_E_INVAL;
12562 }
12563
12564 /* Get MAC address from NV, update CFG info */
12565 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12566 {
12567 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012569 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012570 /* This MAC is not valid, skip it
12571 * This MAC will be got from ini file */
12572 }
12573 else
12574 {
12575 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12576 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12577 VOS_MAC_ADDR_SIZE);
12578 }
12579 }
12580 }
12581 else
12582 {
12583 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12584 return VOS_STATUS_E_FAILURE;
12585 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012586
Jeff Johnson295189b2012-06-20 16:38:30 -070012587
12588 return VOS_STATUS_SUCCESS;
12589}
12590
12591/**---------------------------------------------------------------------------
12592
12593 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12594
12595 \param - pAdapter - Pointer to the HDD
12596
12597 \return - None
12598
12599 --------------------------------------------------------------------------*/
12600VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12601{
12602 eHalStatus halStatus;
12603 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012604 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012605
Jeff Johnson295189b2012-06-20 16:38:30 -070012606
12607 // Send ready indication to the HDD. This will kick off the MAC
12608 // into a 'running' state and should kick off an initial scan.
12609 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12610 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12611 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012612 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 "code %08d [x%08x]",__func__, halStatus, halStatus );
12614 return VOS_STATUS_E_FAILURE;
12615 }
12616
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012617 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12619 // And RIVA will crash
12620 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12621 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012622 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12623 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12624
12625
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 return VOS_STATUS_SUCCESS;
12627}
12628
Jeff Johnson295189b2012-06-20 16:38:30 -070012629/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012630void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012631{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012632
12633 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12634
Jeff Johnson295189b2012-06-20 16:38:30 -070012635}
12636
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012637void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012638{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012639
12640 vos_wake_lock_release(&wlan_wake_lock, reason);
12641
Jeff Johnson295189b2012-06-20 16:38:30 -070012642}
12643
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012644void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012645{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012646
12647 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12648 reason);
12649
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012650}
12651
Jeff Johnson295189b2012-06-20 16:38:30 -070012652/**---------------------------------------------------------------------------
12653
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012654 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12655 information between Host and Riva
12656
12657 This function gets reported version of FW
12658 It also finds the version of Riva headers used to compile the host
12659 It compares the above two and prints a warning if they are different
12660 It gets the SW and HW version string
12661 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12662 indicating the features they support through a bitmap
12663
12664 \param - pHddCtx - Pointer to HDD context
12665
12666 \return - void
12667
12668 --------------------------------------------------------------------------*/
12669
12670void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12671{
12672
12673 tSirVersionType versionCompiled;
12674 tSirVersionType versionReported;
12675 tSirVersionString versionString;
12676 tANI_U8 fwFeatCapsMsgSupported = 0;
12677 VOS_STATUS vstatus;
12678
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012679 memset(&versionCompiled, 0, sizeof(versionCompiled));
12680 memset(&versionReported, 0, sizeof(versionReported));
12681
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012682 /* retrieve and display WCNSS version information */
12683 do {
12684
12685 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12686 &versionCompiled);
12687 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12688 {
12689 hddLog(VOS_TRACE_LEVEL_FATAL,
12690 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012691 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012692 break;
12693 }
12694
12695 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12696 &versionReported);
12697 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12698 {
12699 hddLog(VOS_TRACE_LEVEL_FATAL,
12700 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012701 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012702 break;
12703 }
12704
12705 if ((versionCompiled.major != versionReported.major) ||
12706 (versionCompiled.minor != versionReported.minor) ||
12707 (versionCompiled.version != versionReported.version) ||
12708 (versionCompiled.revision != versionReported.revision))
12709 {
12710 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12711 "Host expected %u.%u.%u.%u\n",
12712 WLAN_MODULE_NAME,
12713 (int)versionReported.major,
12714 (int)versionReported.minor,
12715 (int)versionReported.version,
12716 (int)versionReported.revision,
12717 (int)versionCompiled.major,
12718 (int)versionCompiled.minor,
12719 (int)versionCompiled.version,
12720 (int)versionCompiled.revision);
12721 }
12722 else
12723 {
12724 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12725 WLAN_MODULE_NAME,
12726 (int)versionReported.major,
12727 (int)versionReported.minor,
12728 (int)versionReported.version,
12729 (int)versionReported.revision);
12730 }
12731
12732 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12733 versionString,
12734 sizeof(versionString));
12735 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12736 {
12737 hddLog(VOS_TRACE_LEVEL_FATAL,
12738 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012739 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012740 break;
12741 }
12742
12743 pr_info("%s: WCNSS software version %s\n",
12744 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012745 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012746
12747 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12748 versionString,
12749 sizeof(versionString));
12750 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12751 {
12752 hddLog(VOS_TRACE_LEVEL_FATAL,
12753 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012754 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012755 break;
12756 }
12757
12758 pr_info("%s: WCNSS hardware version %s\n",
12759 WLAN_MODULE_NAME, versionString);
12760
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012761 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12762 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012763 send the message only if it the riva is 1.1
12764 minor numbers for different riva branches:
12765 0 -> (1.0)Mainline Build
12766 1 -> (1.1)Mainline Build
12767 2->(1.04) Stability Build
12768 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012769 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012770 ((versionReported.minor>=1) && (versionReported.version>=1)))
12771 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12772 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012773
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012774 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012775 {
12776#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12777 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12778 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12779#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012780 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12781 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12782 {
12783 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12784 }
12785
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012786 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012787 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012788
12789 } while (0);
12790
12791}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012792void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12793{
12794 struct sk_buff *skb;
12795 struct nlmsghdr *nlh;
12796 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012797 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012798 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012799
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012800 if (in_interrupt() || irqs_disabled() || in_atomic())
12801 flags = GFP_ATOMIC;
12802
12803 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012804
12805 if(skb == NULL) {
12806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12807 "%s: alloc_skb failed", __func__);
12808 return;
12809 }
12810
12811 nlh = (struct nlmsghdr *)skb->data;
12812 nlh->nlmsg_pid = 0; /* from kernel */
12813 nlh->nlmsg_flags = 0;
12814 nlh->nlmsg_seq = 0;
12815 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12816
12817 ani_hdr = NLMSG_DATA(nlh);
12818 ani_hdr->type = type;
12819
12820 switch(type) {
12821 case WLAN_SVC_SAP_RESTART_IND:
12822 ani_hdr->length = 0;
12823 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12824 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12825 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012826 case WLAN_SVC_WLAN_TP_IND:
12827 ani_hdr->length = len;
12828 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12829 + len));
12830 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12831 memcpy(nl_data, data, len);
12832 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12833 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012834 case WLAN_MSG_RPS_ENABLE_IND:
12835 ani_hdr->length = len;
12836 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12837 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12838 memcpy(nl_data, data, len);
12839 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12840 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012841 default:
12842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12843 "Attempt to send unknown nlink message %d", type);
12844 kfree_skb(skb);
12845 return;
12846 }
12847
12848 nl_srv_bcast(skb);
12849
12850 return;
12851}
12852
Bhargav Shahd0715912015-10-01 18:17:37 +053012853/**
12854 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12855 * @pHddCtx: Valid Global HDD context pointer
12856 * @rx_packets: Number of RX packet in perticular time
12857 *
12858 * Based on the RX packet this function calculate next value of tcp delack.
12859 * This function compare rx packet value to high and low threshold limit.
12860 *
12861 * Return: void
12862 */
12863void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12864{
12865 /* average of rx_packets and prev_rx is taken so that
12866 bus width doesnot fluctuate much */
12867 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012868 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012869
Bhargav Shahd0715912015-10-01 18:17:37 +053012870 pHddCtx->prev_rx = rx_packets;
12871 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012872 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053012873 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053012874 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053012875
12876 hdd_set_delack_value(pHddCtx, next_rx_level);
12877}
12878
12879#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12880
12881/**
12882 * hdd_tcp_delack_compute_function() - get link status
12883 * @priv: Valid Global HDD context pointer
12884 *
12885 * This function find number of RX packet during timer life span.
12886 * It request tcp delack with number of RX packet and re-configure delack timer
12887 * for tcpDelAckComputeInterval timer interval.
12888 *
12889 * Return: void
12890 */
12891void hdd_tcp_delack_compute_function(void *priv)
12892{
12893 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12894 hdd_adapter_t *pAdapter = NULL;
12895 v_U32_t rx_packets = 0;
12896 hdd_adapter_list_node_t *pAdapterNode = NULL;
12897 VOS_STATUS status = 0;
12898
12899 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12900 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12901 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12902 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12903 continue;
12904
12905 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12906 pAdapter->prev_rx_packets);
12907 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12908 }
12909
12910 hdd_request_tcp_delack(pHddCtx, rx_packets);
12911
12912 vos_timer_start(&pHddCtx->delack_timer,
12913 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12914}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012915
12916/**---------------------------------------------------------------------------
12917
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012918 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12919
12920 \param - pHddCtx - Pointer to the hdd context
12921
12922 \return - true if hardware supports 5GHz
12923
12924 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012925boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012926{
12927 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12928 * then hardware support 5Ghz.
12929 */
12930 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12931 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012933 return true;
12934 }
12935 else
12936 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012938 __func__);
12939 return false;
12940 }
12941}
12942
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012943/**---------------------------------------------------------------------------
12944
12945 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12946 generate function
12947
12948 This is generate the random mac address for WLAN interface
12949
12950 \param - pHddCtx - Pointer to HDD context
12951 idx - Start interface index to get auto
12952 generated mac addr.
12953 mac_addr - Mac address
12954
12955 \return - 0 for success, < 0 for failure
12956
12957 --------------------------------------------------------------------------*/
12958
12959static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12960 int idx, v_MACADDR_t mac_addr)
12961{
12962 int i;
12963 unsigned int serialno;
12964 serialno = wcnss_get_serial_number();
12965
12966 if (0 != serialno)
12967 {
12968 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12969 bytes of the serial number that can be used to generate
12970 the other 3 bytes of the MAC address. Mask off all but
12971 the lower 3 bytes (this will also make sure we don't
12972 overflow in the next step) */
12973 serialno &= 0x00FFFFFF;
12974
12975 /* we need a unique address for each session */
12976 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12977
12978 /* autogen other Mac addresses */
12979 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12980 {
12981 /* start with the entire default address */
12982 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12983 /* then replace the lower 3 bytes */
12984 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12985 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12986 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12987
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012988 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12989 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12990 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12991 VOS_MAX_CONCURRENCY_PERSONA;
12992
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012993 serialno++;
12994 hddLog(VOS_TRACE_LEVEL_ERROR,
12995 "%s: Derived Mac Addr: "
12996 MAC_ADDRESS_STR, __func__,
12997 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12998 }
12999
13000 }
13001 else
13002 {
13003 hddLog(LOGE, FL("Failed to Get Serial NO"));
13004 return -1;
13005 }
13006 return 0;
13007}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013008
Katya Nigame7b69a82015-04-28 15:24:06 +053013009int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13010{
13011 VOS_STATUS status;
13012 v_CONTEXT_t pVosContext= NULL;
13013 hdd_adapter_t *pAdapter= NULL;
13014
13015 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13016
13017 if (NULL == pVosContext)
13018 {
13019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13020 "%s: Trying to open VOSS without a PreOpen", __func__);
13021 VOS_ASSERT(0);
13022 return VOS_STATUS_E_FAILURE;
13023 }
13024
13025 status = vos_nv_open();
13026 if (!VOS_IS_STATUS_SUCCESS(status))
13027 {
13028 /* NV module cannot be initialized */
13029 hddLog( VOS_TRACE_LEVEL_FATAL,
13030 "%s: vos_nv_open failed", __func__);
13031 return VOS_STATUS_E_FAILURE;
13032 }
13033
13034 status = vos_init_wiphy_from_nv_bin();
13035 if (!VOS_IS_STATUS_SUCCESS(status))
13036 {
13037 /* NV module cannot be initialized */
13038 hddLog( VOS_TRACE_LEVEL_FATAL,
13039 "%s: vos_init_wiphy failed", __func__);
13040 goto err_vos_nv_close;
13041 }
13042
13043 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13044 if ( !VOS_IS_STATUS_SUCCESS( status ))
13045 {
13046 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13047 goto err_vos_nv_close;
13048 }
13049
13050 status = vos_mon_start( pVosContext );
13051 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13052 {
13053 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13054 goto err_vosclose;
13055 }
13056
13057 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
13058 WDA_featureCapsExchange(pVosContext);
13059 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13060
13061 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13062 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13063 if( pAdapter == NULL )
13064 {
13065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13066 goto err_close_adapter;
13067 }
13068
13069 //Initialize the nlink service
13070 if(nl_srv_init() != 0)
13071 {
13072 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13073 goto err_close_adapter;
13074 }
13075 return VOS_STATUS_SUCCESS;
13076
13077err_close_adapter:
13078 hdd_close_all_adapters( pHddCtx );
13079 vos_mon_stop( pVosContext );
13080err_vosclose:
13081 status = vos_sched_close( pVosContext );
13082 if (!VOS_IS_STATUS_SUCCESS(status)) {
13083 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13084 "%s: Failed to close VOSS Scheduler", __func__);
13085 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13086 }
13087 vos_close(pVosContext );
13088
13089err_vos_nv_close:
13090 vos_nv_close();
13091
13092return status;
13093}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013094/**---------------------------------------------------------------------------
13095
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013096 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13097 completed to flush out the scan results
13098
13099 11d scan is done during driver load and is a passive scan on all
13100 channels supported by the device, 11d scans may find some APs on
13101 frequencies which are forbidden to be used in the regulatory domain
13102 the device is operating in. If these APs are notified to the supplicant
13103 it may try to connect to these APs, thus flush out all the scan results
13104 which are present in SME after 11d scan is done.
13105
13106 \return - eHalStatus
13107
13108 --------------------------------------------------------------------------*/
13109static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13110 tANI_U32 scanId, eCsrScanStatus status)
13111{
13112 ENTER();
13113
13114 sme_ScanFlushResult(halHandle, 0);
13115
13116 EXIT();
13117
13118 return eHAL_STATUS_SUCCESS;
13119}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013120/**---------------------------------------------------------------------------
13121
13122 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13123 logging is completed successfully.
13124
13125 \return - None
13126
13127 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013128void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013129{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013130 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013131
13132 if (NULL == pHddCtx)
13133 {
13134 hddLog(VOS_TRACE_LEVEL_ERROR,
13135 "%s: HDD context is NULL",__func__);
13136 return;
13137 }
13138
c_manjeecfd1efb2015-09-25 19:32:34 +053013139 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013140 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013141 {
13142 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13143 pHddCtx->mgmt_frame_logging = TRUE;
13144 }
13145 else
13146 {
13147 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13148 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013149 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013150 }
13151
c_manjeecfd1efb2015-09-25 19:32:34 +053013152 /*Check feature supported by FW*/
13153 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13154 {
13155 //Store fwr mem dump size given by firmware.
13156 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13157 }
13158 else
13159 {
13160 wlan_store_fwr_mem_dump_size(0);
13161 }
13162
13163
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013164}
13165/**---------------------------------------------------------------------------
13166
13167 \brief hdd_init_frame_logging - function to initialize frame logging.
13168 Currently only Mgmt Frames are logged in both TX
13169 and Rx direction and are sent to userspace
13170 application using logger thread when queried.
13171
13172 \return - None
13173
13174 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013175void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013176{
13177 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013178 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013179
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013180 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13181 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013182 {
13183 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13184 return;
13185 }
13186
c_manjeecfd1efb2015-09-25 19:32:34 +053013187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013188 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13189 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013190 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13191 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013192
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013193 if (pHddCtx->cfg_ini->enableFWLogging ||
13194 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013195 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013196 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013197 }
13198
Sushant Kaushik46804902015-07-08 14:46:03 +053013199 if (pHddCtx->cfg_ini->enableMgmtLogging)
13200 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013201 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013202 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013203 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13204 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013205 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013206 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013207 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13208 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13209 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013210 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013211 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013212 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013213 {
13214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13215 return;
13216 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013217 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13218 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13219 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13220 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013221 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013222
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013223 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013224
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013225 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013226 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013227 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013228 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013229 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13230 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013231
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013232 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013233
13234 if (eHAL_STATUS_SUCCESS != halStatus)
13235 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013236 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13237 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013238 }
13239
13240 return;
13241}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013242
Bhargav shah23c94942015-10-13 12:48:35 +053013243static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13244{
13245 hdd_adapter_t *adapter;
13246 hdd_adapter_list_node_t *adapter_node, *next;
13247 VOS_STATUS status = VOS_STATUS_SUCCESS;
13248 struct wlan_rps_data rps_data;
13249 int count;
13250
13251 if(!hdd_ctxt->cfg_ini->rps_mask)
13252 {
13253 return;
13254 }
13255
13256 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13257 {
13258 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13259 }
13260
13261 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13262
13263 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13264 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13265 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13266
13267 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13268
13269 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13270 {
13271 adapter = adapter_node->pAdapter;
13272 if (NULL != adapter) {
13273 strlcpy(rps_data.ifname, adapter->dev->name,
13274 sizeof(rps_data.ifname));
13275 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13276 (void *)&rps_data,sizeof(rps_data));
13277 }
13278 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13279 adapter_node = next;
13280 }
13281}
13282
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013283void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13284{
13285 scan_context_t *scan_ctx =
13286 container_of(work, scan_context_t, scan_work.work);
13287
13288 if (NULL == scan_ctx)
13289 {
13290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13291 FL("scan_ctx is NULL"));
13292 return;
13293 }
13294
13295 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13296 return;
13297
13298 scan_ctx->attempt++;
13299
13300 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13301#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13302 scan_ctx->dev,
13303#endif
13304 scan_ctx->scan_request);
13305}
13306
13307int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13308 struct wiphy *wiphy,
13309#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13310 struct net_device *dev,
13311#endif
13312 struct cfg80211_scan_request *request)
13313{
13314 scan_context_t *scan_ctx;
13315
13316 ENTER();
13317 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13318 {
13319 return -1;
13320 }
13321
13322 scan_ctx = &pHddCtx->scan_ctxt;
13323
13324 scan_ctx->wiphy = wiphy;
13325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13326 scan_ctx->dev = dev;
13327#endif
13328
13329 scan_ctx->scan_request = request;
13330
13331 EXIT();
13332 return 0;
13333}
13334
13335void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13336 struct wiphy *wiphy,
13337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13338 struct net_device *dev,
13339#endif
13340 struct cfg80211_scan_request *request,
13341 unsigned long delay)
13342{
13343 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13344 {
13345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13346 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13347#else
13348 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13349#endif
13350 pHddCtx->scan_ctxt.attempt = 0;
13351 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13352 }
13353 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13354}
13355
13356void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13357{
13358 scan_ctx->magic = 0;
13359 scan_ctx->attempt = 0;
13360 scan_ctx->reject = 0;
13361 scan_ctx->scan_request = NULL;
13362
13363 return;
13364}
13365
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013366/**---------------------------------------------------------------------------
13367
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 \brief hdd_wlan_startup() - HDD init function
13369
13370 This is the driver startup code executed once a WLAN device has been detected
13371
13372 \param - dev - Pointer to the underlying device
13373
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013374 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013375
13376 --------------------------------------------------------------------------*/
13377
13378int hdd_wlan_startup(struct device *dev )
13379{
13380 VOS_STATUS status;
13381 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013382 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013383 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 hdd_context_t *pHddCtx = NULL;
13385 v_CONTEXT_t pVosContext= NULL;
13386#ifdef WLAN_BTAMP_FEATURE
13387 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13388 WLANBAP_ConfigType btAmpConfig;
13389 hdd_config_t *pConfig;
13390#endif
13391 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013393 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013394
13395 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 /*
13397 * cfg80211: wiphy allocation
13398 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013399 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013400
13401 if(wiphy == NULL)
13402 {
13403 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013404 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 pHddCtx = wiphy_priv(wiphy);
13407
Jeff Johnson295189b2012-06-20 16:38:30 -070013408 //Initialize the adapter context to zeros.
13409 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13410
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013412 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013413 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013414
13415 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13416
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013417 /* register for riva power on lock to platform driver
13418 * Locking power early to ensure FW doesn't reset by kernel while
13419 * host driver is busy initializing itself */
13420 if (req_riva_power_on_lock("wlan"))
13421 {
13422 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13423 __func__);
13424 goto err_free_hdd_context;
13425 }
13426
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 /*Get vos context here bcoz vos_open requires it*/
13428 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13429
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013430 if(pVosContext == NULL)
13431 {
13432 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13433 goto err_free_hdd_context;
13434 }
13435
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 //Save the Global VOSS context in adapter context for future.
13437 pHddCtx->pvosContext = pVosContext;
13438
13439 //Save the adapter context in global context for future.
13440 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13441
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013443 pHddCtx->last_scan_reject_session_id = 0xFF;
13444 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013445 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013446 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013447
13448 init_completion(&pHddCtx->full_pwr_comp_var);
13449 init_completion(&pHddCtx->standby_comp_var);
13450 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013451 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013452 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013453 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013454 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013455 init_completion(&pHddCtx->mc_sus_event_var);
13456 init_completion(&pHddCtx->tx_sus_event_var);
13457 init_completion(&pHddCtx->rx_sus_event_var);
13458
Amar Singhala49cbc52013-10-08 18:37:44 -070013459
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013460 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013461 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013462
Amar Singhala49cbc52013-10-08 18:37:44 -070013463#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013464 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013465#else
13466 init_completion(&pHddCtx->driver_crda_req);
13467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013468
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013469#ifdef WLAN_FEATURE_EXTSCAN
13470 init_completion(&pHddCtx->ext_scan_context.response_event);
13471#endif /* WLAN_FEATURE_EXTSCAN */
13472
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013473 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013474 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013475
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13477
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013478 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13479 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013480 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013481 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13482 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013483
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013484#ifdef FEATURE_WLAN_TDLS
13485 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13486 * invoked by other instances also) to protect the concurrent
13487 * access for the Adapters by TDLS module.
13488 */
13489 mutex_init(&pHddCtx->tdls_lock);
13490#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013491 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013492 mutex_init(&pHddCtx->wmmLock);
13493
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013494 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013495 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013496
Agarwal Ashish1f422872014-07-22 00:11:55 +053013497 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 // Load all config first as TL config is needed during vos_open
13499 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13500 if(pHddCtx->cfg_ini == NULL)
13501 {
13502 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13503 goto err_free_hdd_context;
13504 }
13505
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013506 hdd_request_manager_init();
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13509
13510 // Read and parse the qcom_cfg.ini file
13511 status = hdd_parse_config_ini( pHddCtx );
13512 if ( VOS_STATUS_SUCCESS != status )
13513 {
13514 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13515 __func__, WLAN_INI_FILE);
13516 goto err_config;
13517 }
Arif Hussaind5218912013-12-05 01:10:55 -080013518#ifdef MEMORY_DEBUG
13519 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13520 vos_mem_init();
13521
13522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13523 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013525
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013526 /* INI has been read, initialise the configuredMcastBcastFilter with
13527 * INI value as this will serve as the default value
13528 */
13529 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13530 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13531 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013532
13533 if (false == hdd_is_5g_supported(pHddCtx))
13534 {
13535 //5Ghz is not supported.
13536 if (1 != pHddCtx->cfg_ini->nBandCapability)
13537 {
13538 hddLog(VOS_TRACE_LEVEL_INFO,
13539 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13540 pHddCtx->cfg_ini->nBandCapability = 1;
13541 }
13542 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013543
13544 /* If SNR Monitoring is enabled, FW has to parse all beacons
13545 * for calcaluting and storing the average SNR, so set Nth beacon
13546 * filter to 1 to enable FW to parse all the beaocons
13547 */
13548 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13549 {
13550 /* The log level is deliberately set to WARN as overriding
13551 * nthBeaconFilter to 1 will increase power cosumption and this
13552 * might just prove helpful to detect the power issue.
13553 */
13554 hddLog(VOS_TRACE_LEVEL_WARN,
13555 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13556 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013559 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013561 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013563 hddLog(VOS_TRACE_LEVEL_FATAL,
13564 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13565 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013567
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013568 // Update VOS trace levels based upon the cfg.ini
13569 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13570 pHddCtx->cfg_ini->vosTraceEnableBAP);
13571 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13572 pHddCtx->cfg_ini->vosTraceEnableTL);
13573 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13574 pHddCtx->cfg_ini->vosTraceEnableWDI);
13575 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13576 pHddCtx->cfg_ini->vosTraceEnableHDD);
13577 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13578 pHddCtx->cfg_ini->vosTraceEnableSME);
13579 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13580 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013581 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13582 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013583 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13584 pHddCtx->cfg_ini->vosTraceEnableWDA);
13585 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13586 pHddCtx->cfg_ini->vosTraceEnableSYS);
13587 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13588 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013589 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13590 pHddCtx->cfg_ini->vosTraceEnableSAP);
13591 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13592 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013593
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 // Update WDI trace levels based upon the cfg.ini
13595 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13596 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13597 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13598 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13599 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13600 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13601 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13602 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013603
Jeff Johnson88ba7742013-02-27 14:36:02 -080013604 if (VOS_FTM_MODE == hdd_get_conparam())
13605 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13607 {
13608 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13609 goto err_free_hdd_context;
13610 }
13611 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013612 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013613 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013615 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
Katya Nigame7b69a82015-04-28 15:24:06 +053013617 if( VOS_MONITOR_MODE == hdd_get_conparam())
13618 {
13619 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13620 {
13621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13622 goto err_free_hdd_context;
13623 }
13624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13625 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13626 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13627 return VOS_STATUS_SUCCESS;
13628 }
13629
Jeff Johnson88ba7742013-02-27 14:36:02 -080013630 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13632 {
13633 status = vos_watchdog_open(pVosContext,
13634 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13635
13636 if(!VOS_IS_STATUS_SUCCESS( status ))
13637 {
13638 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013639 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 }
13641 }
13642
13643 pHddCtx->isLogpInProgress = FALSE;
13644 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13645
Amar Singhala49cbc52013-10-08 18:37:44 -070013646#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013647 /* initialize the NV module. This is required so that
13648 we can initialize the channel information in wiphy
13649 from the NV.bin data. The channel information in
13650 wiphy needs to be initialized before wiphy registration */
13651
13652 status = vos_nv_open();
13653 if (!VOS_IS_STATUS_SUCCESS(status))
13654 {
13655 /* NV module cannot be initialized */
13656 hddLog( VOS_TRACE_LEVEL_FATAL,
13657 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013658 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013659 }
13660
13661 status = vos_init_wiphy_from_nv_bin();
13662 if (!VOS_IS_STATUS_SUCCESS(status))
13663 {
13664 /* NV module cannot be initialized */
13665 hddLog( VOS_TRACE_LEVEL_FATAL,
13666 "%s: vos_init_wiphy failed", __func__);
13667 goto err_vos_nv_close;
13668 }
13669
Amar Singhala49cbc52013-10-08 18:37:44 -070013670#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013671 //Initialize the nlink service
13672 if(nl_srv_init() != 0)
13673 {
13674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13675 goto err_vos_nv_close;
13676 }
13677
13678#ifdef WLAN_KD_READY_NOTIFIER
13679 pHddCtx->kd_nl_init = 1;
13680#endif /* WLAN_KD_READY_NOTIFIER */
13681
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013682 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013683 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 if ( !VOS_IS_STATUS_SUCCESS( status ))
13685 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013686 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013687 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 }
13689
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13691
13692 if ( NULL == pHddCtx->hHal )
13693 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013694 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 goto err_vosclose;
13696 }
13697
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013698 status = vos_preStart( pHddCtx->pvosContext );
13699 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13700 {
13701 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013702 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013703 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013704
Arif Hussaineaf68602013-12-30 23:10:44 -080013705 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13706 {
13707 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13709 __func__, enable_dfs_chan_scan);
13710 }
13711 if (0 == enable_11d || 1 == enable_11d)
13712 {
13713 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13715 __func__, enable_11d);
13716 }
13717
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013718 /* Note that the vos_preStart() sequence triggers the cfg download.
13719 The cfg download must occur before we update the SME config
13720 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 status = hdd_set_sme_config( pHddCtx );
13722
13723 if ( VOS_STATUS_SUCCESS != status )
13724 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013725 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013726 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013728
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 /* In the integrated architecture we update the configuration from
13730 the INI file and from NV before vOSS has been started so that
13731 the final contents are available to send down to the cCPU */
13732
13733 // Apply the cfg.ini to cfg.dat
13734 if (FALSE == hdd_update_config_dat(pHddCtx))
13735 {
13736 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013737 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 }
13739
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013740 // Get mac addr from platform driver
13741 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13742
13743 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013745 /* Store the mac addr for first interface */
13746 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13747
13748 hddLog(VOS_TRACE_LEVEL_ERROR,
13749 "%s: WLAN Mac Addr: "
13750 MAC_ADDRESS_STR, __func__,
13751 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13752
13753 /* Here, passing Arg2 as 1 because we do not want to change the
13754 last 3 bytes (means non OUI bytes) of first interface mac
13755 addr.
13756 */
13757 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13758 {
13759 hddLog(VOS_TRACE_LEVEL_ERROR,
13760 "%s: Failed to generate wlan interface mac addr "
13761 "using MAC from ini file ", __func__);
13762 }
13763 }
13764 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13765 {
13766 // Apply the NV to cfg.dat
13767 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013768#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13769 /* There was not a valid set of MAC Addresses in NV. See if the
13770 default addresses were modified by the cfg.ini settings. If so,
13771 we'll use them, but if not, we'll autogenerate a set of MAC
13772 addresses based upon the device serial number */
13773
13774 static const v_MACADDR_t default_address =
13775 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013776
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013777 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13778 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 {
13780 /* cfg.ini has the default address, invoke autogen logic */
13781
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013782 /* Here, passing Arg2 as 0 because we want to change the
13783 last 3 bytes (means non OUI bytes) of all the interfaces
13784 mac addr.
13785 */
13786 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13787 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013789 hddLog(VOS_TRACE_LEVEL_ERROR,
13790 "%s: Failed to generate wlan interface mac addr "
13791 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13792 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 }
13795 else
13796#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13797 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013798 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 "%s: Invalid MAC address in NV, using MAC from ini file "
13800 MAC_ADDRESS_STR, __func__,
13801 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13802 }
13803 }
13804 {
13805 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013806
13807 /* Set the MAC Address Currently this is used by HAL to
13808 * add self sta. Remove this once self sta is added as
13809 * part of session open.
13810 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13812 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13813 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013814
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 if (!HAL_STATUS_SUCCESS( halStatus ))
13816 {
13817 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13818 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013819 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 }
13821 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013822
13823 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13824 Note: Firmware image will be read and downloaded inside vos_start API */
13825 status = vos_start( pHddCtx->pvosContext );
13826 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13827 {
13828 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013829 if (isSsrPanicOnFailure())
13830 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013831 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 }
13833
Leo Chang6cec3e22014-01-21 15:33:49 -080013834#ifdef FEATURE_WLAN_CH_AVOID
13835 /* Plug in avoid channel notification callback
13836 * This should happen before ADD_SELF_STA
13837 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013838
13839 /* check the Channel Avoidance is enabled */
13840 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13841 {
13842 sme_AddChAvoidCallback(pHddCtx->hHal,
13843 hdd_hostapd_ch_avoid_cb);
13844 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013845#endif /* FEATURE_WLAN_CH_AVOID */
13846
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013847 /* Exchange capability info between Host and FW and also get versioning info from FW */
13848 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013849
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013850#ifdef CONFIG_ENABLE_LINUX_REG
13851 status = wlan_hdd_init_channels(pHddCtx);
13852 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13853 {
13854 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13855 __func__);
13856 goto err_vosstop;
13857 }
13858#endif
13859
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 status = hdd_post_voss_start_config( pHddCtx );
13861 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13862 {
13863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13864 __func__);
13865 goto err_vosstop;
13866 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013867
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053013868 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
13869
Amar Singhala49cbc52013-10-08 18:37:44 -070013870#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013871 wlan_hdd_cfg80211_update_reg_info( wiphy );
13872
13873 /* registration of wiphy dev with cfg80211 */
13874 if (0 > wlan_hdd_cfg80211_register(wiphy))
13875 {
13876 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13877 goto err_vosstop;
13878 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013880
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013881#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013882 /* registration of wiphy dev with cfg80211 */
13883 if (0 > wlan_hdd_cfg80211_register(wiphy))
13884 {
13885 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13886 goto err_vosstop;
13887 }
13888
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013889 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013890 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13891 {
13892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13893 __func__);
13894 goto err_unregister_wiphy;
13895 }
13896#endif
13897
c_hpothu4a298be2014-12-22 21:12:51 +053013898 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13899
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13901 {
13902 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13903 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13904 }
13905 else
13906 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13908 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13909 if (pAdapter != NULL)
13910 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013911 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013913 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13914 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13915 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013916
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013917 /* Generate the P2P Device Address. This consists of the device's
13918 * primary MAC address with the locally administered bit set.
13919 */
13920 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013921 }
13922 else
13923 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013924 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13925 if (p2p_dev_addr != NULL)
13926 {
13927 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13928 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13929 }
13930 else
13931 {
13932 hddLog(VOS_TRACE_LEVEL_FATAL,
13933 "%s: Failed to allocate mac_address for p2p_device",
13934 __func__);
13935 goto err_close_adapter;
13936 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013938
13939 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13940 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13941 if ( NULL == pP2pAdapter )
13942 {
13943 hddLog(VOS_TRACE_LEVEL_FATAL,
13944 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013945 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013946 goto err_close_adapter;
13947 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013948 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013950
13951 if( pAdapter == NULL )
13952 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13954 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013956
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053013957 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
13958 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013959 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
13960 pHddCtx->cfg_ini->enabledefaultSAP,
13961 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
13962 if (!softapAdapter) {
13963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13964 goto err_close_adapter;
13965 }
13966 }
13967
Arif Hussain66559122013-11-21 10:11:40 -080013968 if (country_code)
13969 {
13970 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013971 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013972 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13973#ifndef CONFIG_ENABLE_LINUX_REG
13974 hdd_checkandupdate_phymode(pAdapter, country_code);
13975#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013976 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13977 (void *)(tSmeChangeCountryCallback)
13978 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013979 country_code,
13980 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013981 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013982 if (eHAL_STATUS_SUCCESS == ret)
13983 {
Arif Hussaincb607082013-12-20 11:57:42 -080013984 ret = wait_for_completion_interruptible_timeout(
13985 &pAdapter->change_country_code,
13986 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13987
13988 if (0 >= ret)
13989 {
13990 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13991 "%s: SME while setting country code timed out", __func__);
13992 }
Arif Hussain66559122013-11-21 10:11:40 -080013993 }
13994 else
13995 {
Arif Hussaincb607082013-12-20 11:57:42 -080013996 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13997 "%s: SME Change Country code from module param fail ret=%d",
13998 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013999 }
14000 }
14001
Jeff Johnson295189b2012-06-20 16:38:30 -070014002#ifdef WLAN_BTAMP_FEATURE
14003 vStatus = WLANBAP_Open(pVosContext);
14004 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14005 {
14006 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14007 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014008 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 }
14010
14011 vStatus = BSL_Init(pVosContext);
14012 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14013 {
14014 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14015 "%s: Failed to Init BSL",__func__);
14016 goto err_bap_close;
14017 }
14018 vStatus = WLANBAP_Start(pVosContext);
14019 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14020 {
14021 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14022 "%s: Failed to start TL",__func__);
14023 goto err_bap_close;
14024 }
14025
14026 pConfig = pHddCtx->cfg_ini;
14027 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14028 status = WLANBAP_SetConfig(&btAmpConfig);
14029
14030#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014031
Mihir Shete9c238772014-10-15 14:35:16 +053014032 /*
14033 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14034 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14035 * which is greater than 0xf. So the below check is safe to make
14036 * sure that there is no entry for UapsdMask in the ini
14037 */
14038 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14039 {
14040 if(IS_DYNAMIC_WMM_PS_ENABLED)
14041 {
14042 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14043 __func__);
14044 pHddCtx->cfg_ini->UapsdMask =
14045 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14046 }
14047 else
14048 {
14049 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14050 __func__);
14051 pHddCtx->cfg_ini->UapsdMask =
14052 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14053 }
14054 }
14055
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014056#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14057 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14058 {
14059 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14060 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14061 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14062 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14063 }
14064#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014065
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014066 wlan_hdd_tdls_init(pHddCtx);
14067
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014068 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14069
14070 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14071 wlan_hdd_schedule_defer_scan);
14072
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014073 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14074
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 /* Register with platform driver as client for Suspend/Resume */
14076 status = hddRegisterPmOps(pHddCtx);
14077 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14078 {
14079 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14080#ifdef WLAN_BTAMP_FEATURE
14081 goto err_bap_stop;
14082#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014083 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014084#endif //WLAN_BTAMP_FEATURE
14085 }
14086
Yue Ma0d4891e2013-08-06 17:01:45 -070014087 /* Open debugfs interface */
14088 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14089 {
14090 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14091 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014092 }
14093
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 /* Register TM level change handler function to the platform */
14095 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14096 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14097 {
14098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14099 goto err_unregister_pmops;
14100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014101
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 // register net device notifier for device change notification
14103 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14104
14105 if(ret < 0)
14106 {
14107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014108 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 }
14110
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 //Initialize the BTC service
14112 if(btc_activate_service(pHddCtx) != 0)
14113 {
14114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014115 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014118#ifdef FEATURE_OEM_DATA_SUPPORT
14119 //Initialize the OEM service
14120 if (oem_activate_service(pHddCtx) != 0)
14121 {
14122 hddLog(VOS_TRACE_LEVEL_FATAL,
14123 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014124 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014125 }
14126#endif
14127
Jeff Johnson295189b2012-06-20 16:38:30 -070014128#ifdef PTT_SOCK_SVC_ENABLE
14129 //Initialize the PTT service
14130 if(ptt_sock_activate_svc(pHddCtx) != 0)
14131 {
14132 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014133 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 }
14135#endif
14136
Abhishek Singh00b71972016-01-07 10:51:04 +053014137#ifdef WLAN_FEATURE_RMC
14138 if (hdd_open_cesium_nl_sock() < 0)
14139 {
14140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014141 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014142 }
14143#endif
14144
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014145#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14146 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14147 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014148 if(wlan_logging_sock_activate_svc(
14149 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014150 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14151 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14152 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014153 {
14154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14155 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014156 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014157 }
14158 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14159 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014160 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14161 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014162 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14163 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014164 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014165
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014166 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14167 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014168 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014169 pHddCtx->cfg_ini->enableContFWLogging ||
14170 pHddCtx->cfg_ini->enableFwrMemDump )
14171 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014172 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014173 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014174 }
14175 else
14176 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014177 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014178 }
14179
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014180#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014181
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014182#ifdef SAP_AUTH_OFFLOAD
14183 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14184 {
14185 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14186 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14187 }
14188#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014189
Sushant Kaushik215778f2015-05-21 14:05:36 +053014190 if (vos_is_multicast_logging())
14191 wlan_logging_set_log_level();
14192
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 hdd_register_mcast_bcast_filter(pHddCtx);
Bala Venkateshe65810a2019-02-18 20:32:36 +053014194
14195 /* Action frame registered in one adapter which will
14196 * applicable to all interfaces
14197 */
14198 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014199
14200 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014201 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014202
Jeff Johnsone7245742012-09-05 17:12:55 -070014203#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14204 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014205 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014206 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014207
Jeff Johnsone7245742012-09-05 17:12:55 -070014208#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014209 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014210 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014211 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014212
Jeff Johnsone7245742012-09-05 17:12:55 -070014213
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014214 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14215 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014216
Katya Nigam5c306ea2014-06-19 15:39:54 +053014217 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014218 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014219 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014220
14221#ifdef FEATURE_WLAN_SCAN_PNO
14222 /*SME must send channel update configuration to RIVA*/
14223 sme_UpdateChannelConfig(pHddCtx->hHal);
14224#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014225 /* Send the update default channel list to the FW*/
14226 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014227
14228 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014229 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14230 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014231 sme_SetDefDot11Mode(pHddCtx->hHal);
14232
Abhishek Singha306a442013-11-07 18:39:01 +053014233#ifndef CONFIG_ENABLE_LINUX_REG
14234 /*updating wiphy so that regulatory user hints can be processed*/
14235 if (wiphy)
14236 {
14237 regulatory_hint(wiphy, "00");
14238 }
14239#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014240 // Initialize the restart logic
14241 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014242
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014243 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14244 vos_wdthread_init_timer_work(vos_process_wd_timer);
14245 /* Initialize the timer to detect thread stuck issues */
14246 vos_thread_stuck_timer_init(
14247 &((VosContextType*)pVosContext)->vosWatchdog);
14248 }
14249
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014250 //Register the traffic monitor timer now
14251 if ( pHddCtx->cfg_ini->dynSplitscan)
14252 {
14253 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14254 VOS_TIMER_TYPE_SW,
14255 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14256 (void *)pHddCtx);
14257 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014258 wlan_hdd_cfg80211_nan_init(pHddCtx);
14259
Bhargav Shahd0715912015-10-01 18:17:37 +053014260 mutex_init(&pHddCtx->cur_rx_level_lock);
14261 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14262 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014263 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14264 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014265
Dino Mycle6fb96c12014-06-10 11:52:40 +053014266#ifdef WLAN_FEATURE_EXTSCAN
14267 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14268 wlan_hdd_cfg80211_extscan_callback,
14269 pHddCtx);
14270#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014271
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014272#ifdef FEATURE_OEM_DATA_SUPPORT
14273 sme_OemDataRegisterCallback(pHddCtx->hHal,
14274 wlan_hdd_cfg80211_oemdata_callback,
14275 pHddCtx);
14276#endif /* FEATURE_OEM_DATA_SUPPORT */
14277
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014278 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014279#ifdef WLAN_NS_OFFLOAD
14280 // Register IPv6 notifier to notify if any change in IP
14281 // So that we can reconfigure the offload parameters
14282 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14283 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14284 if (ret)
14285 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014287 }
14288 else
14289 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014291 }
14292#endif
14293
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014294 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14295
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014296 // Register IPv4 notifier to notify if any change in IP
14297 // So that we can reconfigure the offload parameters
14298 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14299 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14300 if (ret)
14301 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014303 }
14304 else
14305 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014307 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014308 /*Fw mem dump procfs initialization*/
14309 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014310 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014311
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014312 pHddCtx->is_ap_mode_wow_supported =
14313 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014314
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014315 pHddCtx->is_fatal_event_log_sup =
14316 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14317 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14318 pHddCtx->is_fatal_event_log_sup);
14319
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014320 hdd_assoc_registerFwdEapolCB(pVosContext);
14321
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014322 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 goto success;
14324
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014325err_open_cesium_nl_sock:
14326#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14327 hdd_close_cesium_nl_sock();
14328#endif
14329
14330err_ptt_sock_activate_svc:
14331#ifdef PTT_SOCK_SVC_ENABLE
14332 ptt_sock_deactivate_svc(pHddCtx);
14333#endif
14334
14335err_oem_activate_service:
14336#ifdef FEATURE_OEM_DATA_SUPPORT
14337 oem_deactivate_service();
14338#endif
14339
14340err_btc_activate_service:
14341 btc_deactivate_service();
14342
Jeff Johnson295189b2012-06-20 16:38:30 -070014343err_reg_netdev:
14344 unregister_netdevice_notifier(&hdd_netdev_notifier);
14345
Jeff Johnson295189b2012-06-20 16:38:30 -070014346err_unregister_pmops:
14347 hddDevTmUnregisterNotifyCallback(pHddCtx);
14348 hddDeregisterPmOps(pHddCtx);
14349
Yue Ma0d4891e2013-08-06 17:01:45 -070014350 hdd_debugfs_exit(pHddCtx);
14351
Jeff Johnson295189b2012-06-20 16:38:30 -070014352#ifdef WLAN_BTAMP_FEATURE
14353err_bap_stop:
14354 WLANBAP_Stop(pVosContext);
14355#endif
14356
14357#ifdef WLAN_BTAMP_FEATURE
14358err_bap_close:
14359 WLANBAP_Close(pVosContext);
14360#endif
14361
Jeff Johnson295189b2012-06-20 16:38:30 -070014362err_close_adapter:
14363 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014364#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014365err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014366#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014367 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014368 hdd_wlan_free_wiphy_channels(wiphy);
14369
Jeff Johnson295189b2012-06-20 16:38:30 -070014370err_vosstop:
14371 vos_stop(pVosContext);
14372
Amar Singhala49cbc52013-10-08 18:37:44 -070014373err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 status = vos_sched_close( pVosContext );
14375 if (!VOS_IS_STATUS_SUCCESS(status)) {
14376 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14377 "%s: Failed to close VOSS Scheduler", __func__);
14378 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14379 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014380 vos_close(pVosContext );
14381
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014382err_nl_srv:
14383#ifdef WLAN_KD_READY_NOTIFIER
14384 nl_srv_exit(pHddCtx->ptt_pid);
14385#else
14386 nl_srv_exit();
14387#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014388err_vos_nv_close:
14389
c_hpothue6a36282014-03-19 12:27:38 +053014390#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014391 vos_nv_close();
14392
c_hpothu70f8d812014-03-22 22:59:23 +053014393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014394
14395err_wdclose:
14396 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14397 vos_watchdog_close(pVosContext);
14398
Jeff Johnson295189b2012-06-20 16:38:30 -070014399err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014400 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014401 kfree(pHddCtx->cfg_ini);
14402 pHddCtx->cfg_ini= NULL;
14403
14404err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014405 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014406 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 wiphy_free(wiphy) ;
14408 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 VOS_BUG(1);
14410
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014411 if (hdd_is_ssr_required())
14412 {
14413 /* WDI timeout had happened during load, so SSR is needed here */
14414 subsystem_restart("wcnss");
14415 msleep(5000);
14416 }
14417 hdd_set_ssr_required (VOS_FALSE);
14418
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014419 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014420
14421success:
14422 EXIT();
14423 return 0;
14424}
14425
14426/**---------------------------------------------------------------------------
14427
Jeff Johnson32d95a32012-09-10 13:15:23 -070014428 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014429
Jeff Johnson32d95a32012-09-10 13:15:23 -070014430 This is the driver entry point - called in different timeline depending
14431 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014432
14433 \param - None
14434
14435 \return - 0 for success, non zero for failure
14436
14437 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014438static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014439{
14440 VOS_STATUS status;
14441 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014442 struct device *dev = NULL;
14443 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014444#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14445 int max_retries = 0;
14446#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014447#ifdef HAVE_CBC_DONE
14448 int max_cbc_retries = 0;
14449#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014450
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014451#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14452 wlan_logging_sock_init_svc();
14453#endif
14454
Jeff Johnson295189b2012-06-20 16:38:30 -070014455 ENTER();
14456
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014457 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014458
14459 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14460 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14461
Jeff Johnson295189b2012-06-20 16:38:30 -070014462#ifdef ANI_BUS_TYPE_PCI
14463
14464 dev = wcnss_wlan_get_device();
14465
14466#endif // ANI_BUS_TYPE_PCI
14467
14468#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014469
14470#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14471 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014472 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014473 msleep(1000);
14474 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014475
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014476 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014477 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014478 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014479#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14480 wlan_logging_sock_deinit_svc();
14481#endif
14482
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014483 return -ENODEV;
14484 }
14485#endif
14486
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014487#ifdef HAVE_CBC_DONE
14488 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14489 msleep(1000);
14490 }
14491 if (max_cbc_retries >= 10) {
14492 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14493 }
14494#endif
14495
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 dev = wcnss_wlan_get_device();
14497#endif // ANI_BUS_TYPE_PLATFORM
14498
14499
14500 do {
14501 if (NULL == dev) {
14502 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14503 ret_status = -1;
14504 break;
14505 }
14506
Jeff Johnson295189b2012-06-20 16:38:30 -070014507#ifdef TIMER_MANAGER
14508 vos_timer_manager_init();
14509#endif
14510
14511 /* Preopen VOSS so that it is ready to start at least SAL */
14512 status = vos_preOpen(&pVosContext);
14513
14514 if (!VOS_IS_STATUS_SUCCESS(status))
14515 {
14516 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14517 ret_status = -1;
14518 break;
14519 }
14520
Sushant Kaushik02beb352015-06-04 15:15:01 +053014521 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014522 hdd_register_debug_callback();
14523
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014524#ifndef MODULE
14525 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14526 */
14527 hdd_set_conparam((v_UINT_t)con_mode);
14528#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014529
14530 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014531 if (hdd_wlan_startup(dev))
14532 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014534 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 vos_preClose( &pVosContext );
14536 ret_status = -1;
14537 break;
14538 }
14539
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 } while (0);
14541
14542 if (0 != ret_status)
14543 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014544#ifdef TIMER_MANAGER
14545 vos_timer_exit();
14546#endif
14547#ifdef MEMORY_DEBUG
14548 vos_mem_exit();
14549#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014550 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014551#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14552 wlan_logging_sock_deinit_svc();
14553#endif
14554
Jeff Johnson295189b2012-06-20 16:38:30 -070014555 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14556 }
14557 else
14558 {
14559 //Send WLAN UP indication to Nlink Service
14560 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14561
14562 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 }
14564
14565 EXIT();
14566
14567 return ret_status;
14568}
14569
Jeff Johnson32d95a32012-09-10 13:15:23 -070014570/**---------------------------------------------------------------------------
14571
14572 \brief hdd_module_init() - Init Function
14573
14574 This is the driver entry point (invoked when module is loaded using insmod)
14575
14576 \param - None
14577
14578 \return - 0 for success, non zero for failure
14579
14580 --------------------------------------------------------------------------*/
14581#ifdef MODULE
14582static int __init hdd_module_init ( void)
14583{
14584 return hdd_driver_init();
14585}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014586#else /* #ifdef MODULE */
14587static int __init hdd_module_init ( void)
14588{
14589 /* Driver initialization is delayed to fwpath_changed_handler */
14590 return 0;
14591}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014592#endif /* #ifdef MODULE */
14593
Jeff Johnson295189b2012-06-20 16:38:30 -070014594
14595/**---------------------------------------------------------------------------
14596
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014597 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014598
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014599 This is the driver exit point (invoked when module is unloaded using rmmod
14600 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014601
14602 \param - None
14603
14604 \return - None
14605
14606 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014607static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014608{
14609 hdd_context_t *pHddCtx = NULL;
14610 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014611 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014612 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014613
14614 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14615
14616 //Get the global vos context
14617 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14618
14619 if(!pVosContext)
14620 {
14621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14622 goto done;
14623 }
14624
14625 //Get the HDD context.
14626 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14627
14628 if(!pHddCtx)
14629 {
14630 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14631 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014632 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14633 {
14634 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14635 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14636 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14637 hdd_wlan_exit(pHddCtx);
14638 vos_preClose( &pVosContext );
14639 goto done;
14640 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014641 else
14642 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014643 /* We wait for active entry threads to exit from driver
14644 * by waiting until rtnl_lock is available.
14645 */
14646 rtnl_lock();
14647 rtnl_unlock();
14648
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014649 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14650 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14651 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14652 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014654 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014655 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14656 msecs_to_jiffies(30000));
14657 if(!rc)
14658 {
14659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14660 "%s:SSR timedout, fatal error", __func__);
14661 VOS_BUG(0);
14662 }
14663 }
14664
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014665 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14666 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014667
c_hpothu8adb97b2014-12-08 19:38:20 +053014668 /* Driver Need to send country code 00 in below condition
14669 * 1) If gCountryCodePriority is set to 1; and last country
14670 * code set is through 11d. This needs to be done in case
14671 * when NV country code is 00.
14672 * This Needs to be done as when kernel store last country
14673 * code and if stored country code is not through 11d,
14674 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14675 * in next load/unload as soon as we get any country through
14676 * 11d. In sme_HandleChangeCountryCodeByUser
14677 * pMsg->countryCode will be last countryCode and
14678 * pMac->scan.countryCode11d will be country through 11d so
14679 * due to mismatch driver will disable 11d.
14680 *
14681 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014682
c_hpothu8adb97b2014-12-08 19:38:20 +053014683 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014684 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014685 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014686 {
14687 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014688 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014689 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14690 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014691
c_hpothu8adb97b2014-12-08 19:38:20 +053014692 //Do all the cleanup before deregistering the driver
14693 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014694 }
14695
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 vos_preClose( &pVosContext );
14697
14698#ifdef TIMER_MANAGER
14699 vos_timer_exit();
14700#endif
14701#ifdef MEMORY_DEBUG
14702 vos_mem_exit();
14703#endif
14704
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014705#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14706 wlan_logging_sock_deinit_svc();
14707#endif
14708
Jeff Johnson295189b2012-06-20 16:38:30 -070014709done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014710 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014711
Jeff Johnson295189b2012-06-20 16:38:30 -070014712 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14713}
14714
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014715/**---------------------------------------------------------------------------
14716
14717 \brief hdd_module_exit() - Exit function
14718
14719 This is the driver exit point (invoked when module is unloaded using rmmod)
14720
14721 \param - None
14722
14723 \return - None
14724
14725 --------------------------------------------------------------------------*/
14726static void __exit hdd_module_exit(void)
14727{
14728 hdd_driver_exit();
14729}
14730
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014731#ifdef MODULE
14732static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014733 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014734{
Jeff Johnson76052702013-04-16 13:55:05 -070014735 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014736}
14737
14738static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014739 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014740{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014741 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014742}
14743#else /* #ifdef MODULE */
14744/**---------------------------------------------------------------------------
14745
Jeff Johnson76052702013-04-16 13:55:05 -070014746 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014747
Jeff Johnson76052702013-04-16 13:55:05 -070014748 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014749 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014750 - invoked when module parameter fwpath is modified from userspace to signal
14751 initializing the WLAN driver or when con_mode is modified from userspace
14752 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014753
14754 \return - 0 for success, non zero for failure
14755
14756 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014757static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014758{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014759 int ret_status;
14760
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014761 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014762 ret_status = hdd_driver_init();
14763 wlan_hdd_inited = ret_status ? 0 : 1;
14764 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014765 }
14766
14767 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014768
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014769 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014770
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014771 ret_status = hdd_driver_init();
14772 wlan_hdd_inited = ret_status ? 0 : 1;
14773 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014774}
14775
Jeff Johnson295189b2012-06-20 16:38:30 -070014776/**---------------------------------------------------------------------------
14777
Jeff Johnson76052702013-04-16 13:55:05 -070014778 \brief fwpath_changed_handler() - Handler Function
14779
14780 Handle changes to the fwpath parameter
14781
14782 \return - 0 for success, non zero for failure
14783
14784 --------------------------------------------------------------------------*/
14785static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014786 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014787{
14788 int ret;
14789
14790 ret = param_set_copystring(kmessage, kp);
14791 if (0 == ret)
14792 ret = kickstart_driver();
14793 return ret;
14794}
14795
14796/**---------------------------------------------------------------------------
14797
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014798 \brief con_mode_handler() -
14799
14800 Handler function for module param con_mode when it is changed by userspace
14801 Dynamically linked - do nothing
14802 Statically linked - exit and init driver, as in rmmod and insmod
14803
Jeff Johnson76052702013-04-16 13:55:05 -070014804 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014805
Jeff Johnson76052702013-04-16 13:55:05 -070014806 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014807
14808 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014809static int con_mode_handler(const char *kmessage,
14810 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014811{
Jeff Johnson76052702013-04-16 13:55:05 -070014812 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014813
Jeff Johnson76052702013-04-16 13:55:05 -070014814 ret = param_set_int(kmessage, kp);
14815 if (0 == ret)
14816 ret = kickstart_driver();
14817 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014818}
14819#endif /* #ifdef MODULE */
14820
14821/**---------------------------------------------------------------------------
14822
Jeff Johnson295189b2012-06-20 16:38:30 -070014823 \brief hdd_get_conparam() -
14824
14825 This is the driver exit point (invoked when module is unloaded using rmmod)
14826
14827 \param - None
14828
14829 \return - tVOS_CON_MODE
14830
14831 --------------------------------------------------------------------------*/
14832tVOS_CON_MODE hdd_get_conparam ( void )
14833{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014834#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014835 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014836#else
14837 return (tVOS_CON_MODE)curr_con_mode;
14838#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014839}
14840void hdd_set_conparam ( v_UINT_t newParam )
14841{
14842 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014843#ifndef MODULE
14844 curr_con_mode = con_mode;
14845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014846}
14847/**---------------------------------------------------------------------------
14848
14849 \brief hdd_softap_sta_deauth() - function
14850
14851 This to take counter measure to handle deauth req from HDD
14852
14853 \param - pAdapter - Pointer to the HDD
14854
14855 \param - enable - boolean value
14856
14857 \return - None
14858
14859 --------------------------------------------------------------------------*/
14860
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014861VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14862 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014863{
Jeff Johnson295189b2012-06-20 16:38:30 -070014864 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014865 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014866 struct hdd_cache_sta_info *cache_sta_info;
14867 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014868
14869 ENTER();
14870
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014871 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014872 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014873
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014874 if (!pSapCtx) {
14875 hddLog(LOGE, "sap context is NULL");
14876 return vosStatus;
14877 }
14878
14879 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14880 pDelStaParams->peerMacAddr);
14881 if (cache_sta_info) {
14882 cache_sta_info->reason_code = pDelStaParams->reason_code;
14883 cache_sta_info->rx_rate =
14884 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14885 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14886 &cache_sta_info->rssi);
14887 }
14888
Jeff Johnson295189b2012-06-20 16:38:30 -070014889 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014890 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014891 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014892
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014893 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014894
14895 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014896 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014897}
14898
14899/**---------------------------------------------------------------------------
14900
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014901 \brief hdd_del_all_sta() - function
14902
14903 This function removes all the stations associated on stopping AP/P2P GO.
14904
14905 \param - pAdapter - Pointer to the HDD
14906
14907 \return - None
14908
14909 --------------------------------------------------------------------------*/
14910
14911int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14912{
14913 v_U16_t i;
14914 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014915 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14916 ptSapContext pSapCtx = NULL;
14917 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14918 if(pSapCtx == NULL){
14919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14920 FL("psapCtx is NULL"));
14921 return 1;
14922 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014923 ENTER();
14924
14925 hddLog(VOS_TRACE_LEVEL_INFO,
14926 "%s: Delete all STAs associated.",__func__);
14927 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14928 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14929 )
14930 {
14931 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14932 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014933 if ((pSapCtx->aStaInfo[i].isUsed) &&
14934 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014935 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014936 struct tagCsrDelStaParams delStaParams;
14937
14938 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014939 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014940 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14941 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014942 &delStaParams);
14943 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014944 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014945 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014946 }
14947 }
14948 }
14949
14950 EXIT();
14951 return 0;
14952}
14953
14954/**---------------------------------------------------------------------------
14955
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 \brief hdd_softap_sta_disassoc() - function
14957
14958 This to take counter measure to handle deauth req from HDD
14959
14960 \param - pAdapter - Pointer to the HDD
14961
14962 \param - enable - boolean value
14963
14964 \return - None
14965
14966 --------------------------------------------------------------------------*/
14967
14968void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14969{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014970 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14971 struct hdd_cache_sta_info *cache_sta_info;
14972 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014973
14974 ENTER();
14975
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014976 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014977
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014978 if (!pSapCtx) {
14979 hddLog(LOGE, "sap context is NULL");
14980 return ;
14981 }
14982
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 //Ignore request to disassoc bcmc station
14984 if( pDestMacAddress[0] & 0x1 )
14985 return;
14986
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014987 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14988 pDestMacAddress);
14989 if (cache_sta_info) {
14990 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14991 cache_sta_info->rx_rate =
14992 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14993 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14994 &cache_sta_info->rssi);
14995 }
14996
Jeff Johnson295189b2012-06-20 16:38:30 -070014997 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14998}
14999
15000void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15001{
15002 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15003
15004 ENTER();
15005
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015006 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015007
15008 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15009}
15010
Jeff Johnson295189b2012-06-20 16:38:30 -070015011/**---------------------------------------------------------------------------
15012 *
15013 * \brief hdd_get__concurrency_mode() -
15014 *
15015 *
15016 * \param - None
15017 *
15018 * \return - CONCURRENCY MODE
15019 *
15020 * --------------------------------------------------------------------------*/
15021tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15022{
15023 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15024 hdd_context_t *pHddCtx;
15025
15026 if (NULL != pVosContext)
15027 {
15028 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15029 if (NULL != pHddCtx)
15030 {
15031 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15032 }
15033 }
15034
15035 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015036 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 return VOS_STA;
15038}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015039v_BOOL_t
15040wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15041{
15042 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015043
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015044 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15045 if (pAdapter == NULL)
15046 {
15047 hddLog(VOS_TRACE_LEVEL_INFO,
15048 FL("GO doesn't exist"));
15049 return TRUE;
15050 }
15051 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15052 {
15053 hddLog(VOS_TRACE_LEVEL_INFO,
15054 FL("GO started"));
15055 return TRUE;
15056 }
15057 else
15058 /* wait till GO changes its interface to p2p device */
15059 hddLog(VOS_TRACE_LEVEL_INFO,
15060 FL("Del_bss called, avoid apps suspend"));
15061 return FALSE;
15062
15063}
Jeff Johnson295189b2012-06-20 16:38:30 -070015064/* Decide whether to allow/not the apps power collapse.
15065 * Allow apps power collapse if we are in connected state.
15066 * if not, allow only if we are in IMPS */
15067v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15068{
15069 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015070 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015071 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15073 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15074 hdd_adapter_t *pAdapter = NULL;
15075 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015076 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015077
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15079 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015080
Yathish9f22e662012-12-10 14:21:35 -080015081 concurrent_state = hdd_get_concurrency_mode();
15082
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015083 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15084 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15085 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015086#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015087
Yathish9f22e662012-12-10 14:21:35 -080015088 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015089 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015090 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15091 return TRUE;
15092#endif
15093
Jeff Johnson295189b2012-06-20 16:38:30 -070015094 /*loop through all adapters. TBD fix for Concurrency */
15095 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15096 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15097 {
15098 pAdapter = pAdapterNode->pAdapter;
15099 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15100 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15101 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015102 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015103 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015104 && pmcState != STOPPED && pmcState != STANDBY &&
15105 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015106 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15107 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015108 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015109 if(pmcState == FULL_POWER &&
15110 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15111 {
15112 /*
15113 * When SCO indication comes from Coex module , host will
15114 * enter in to full power mode, but this should not prevent
15115 * apps processor power collapse.
15116 */
15117 hddLog(LOG1,
15118 FL("Allow apps power collapse"
15119 "even when sco indication is set"));
15120 return TRUE;
15121 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015122 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015123 "pmcState = %d scanRspPending = %d "
15124 "inMiddleOfRoaming = %d connected = %d",
15125 __func__, pmcState, scanRspPending,
15126 inMiddleOfRoaming, hdd_connIsConnected(
15127 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15128 wlan_hdd_get_tdls_stats(pAdapter);
15129 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015130 }
15131 }
15132 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15133 pAdapterNode = pNext;
15134 }
15135 return TRUE;
15136}
15137
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015138/* Decides whether to send suspend notification to Riva
15139 * if any adapter is in BMPS; then it is required */
15140v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15141{
15142 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15143 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15144
15145 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15146 {
15147 return TRUE;
15148 }
15149 return FALSE;
15150}
15151
Jeff Johnson295189b2012-06-20 16:38:30 -070015152void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15153{
15154 switch(mode)
15155 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015156 case VOS_STA_MODE:
15157 case VOS_P2P_CLIENT_MODE:
15158 case VOS_P2P_GO_MODE:
15159 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015160 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015161 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015162 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015163 break;
15164 default:
15165 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015167 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15168 "Number of open sessions for mode %d = %d"),
15169 pHddCtx->concurrency_mode, mode,
15170 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015171}
15172
15173
15174void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15175{
15176 switch(mode)
15177 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015178 case VOS_STA_MODE:
15179 case VOS_P2P_CLIENT_MODE:
15180 case VOS_P2P_GO_MODE:
15181 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015182 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015183 pHddCtx->no_of_open_sessions[mode]--;
15184 if (!(pHddCtx->no_of_open_sessions[mode]))
15185 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 break;
15187 default:
15188 break;
15189 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015190 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15191 "Number of open sessions for mode %d = %d"),
15192 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15193
15194}
15195/**---------------------------------------------------------------------------
15196 *
15197 * \brief wlan_hdd_incr_active_session()
15198 *
15199 * This function increments the number of active sessions
15200 * maintained per device mode
15201 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15202 * Incase of SAP/P2P GO upon bss start it is incremented
15203 *
15204 * \param pHddCtx - HDD Context
15205 * \param mode - device mode
15206 *
15207 * \return - None
15208 *
15209 * --------------------------------------------------------------------------*/
15210void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15211{
15212 switch (mode) {
15213 case VOS_STA_MODE:
15214 case VOS_P2P_CLIENT_MODE:
15215 case VOS_P2P_GO_MODE:
15216 case VOS_STA_SAP_MODE:
15217 pHddCtx->no_of_active_sessions[mode]++;
15218 break;
15219 default:
15220 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15221 break;
15222 }
15223 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15224 mode,
15225 pHddCtx->no_of_active_sessions[mode]);
15226}
15227
15228/**---------------------------------------------------------------------------
15229 *
15230 * \brief wlan_hdd_decr_active_session()
15231 *
15232 * This function decrements the number of active sessions
15233 * maintained per device mode
15234 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15235 * Incase of SAP/P2P GO upon bss stop it is decremented
15236 *
15237 * \param pHddCtx - HDD Context
15238 * \param mode - device mode
15239 *
15240 * \return - None
15241 *
15242 * --------------------------------------------------------------------------*/
15243void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15244{
Bhargav Shahd0715912015-10-01 18:17:37 +053015245
Agarwal Ashish51325b52014-06-16 16:50:49 +053015246 switch (mode) {
15247 case VOS_STA_MODE:
15248 case VOS_P2P_CLIENT_MODE:
15249 case VOS_P2P_GO_MODE:
15250 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015251 if (pHddCtx->no_of_active_sessions[mode] > 0)
15252 pHddCtx->no_of_active_sessions[mode]--;
15253 else
15254 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15255 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015256 break;
15257 default:
15258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15259 break;
15260 }
15261 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15262 mode,
15263 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015264}
15265
Jeff Johnsone7245742012-09-05 17:12:55 -070015266/**---------------------------------------------------------------------------
15267 *
15268 * \brief wlan_hdd_restart_init
15269 *
15270 * This function initalizes restart timer/flag. An internal function.
15271 *
15272 * \param - pHddCtx
15273 *
15274 * \return - None
15275 *
15276 * --------------------------------------------------------------------------*/
15277
15278static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15279{
15280 /* Initialize */
15281 pHddCtx->hdd_restart_retries = 0;
15282 atomic_set(&pHddCtx->isRestartInProgress, 0);
15283 vos_timer_init(&pHddCtx->hdd_restart_timer,
15284 VOS_TIMER_TYPE_SW,
15285 wlan_hdd_restart_timer_cb,
15286 pHddCtx);
15287}
15288/**---------------------------------------------------------------------------
15289 *
15290 * \brief wlan_hdd_restart_deinit
15291 *
15292 * This function cleans up the resources used. An internal function.
15293 *
15294 * \param - pHddCtx
15295 *
15296 * \return - None
15297 *
15298 * --------------------------------------------------------------------------*/
15299
15300static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15301{
15302
15303 VOS_STATUS vos_status;
15304 /* Block any further calls */
15305 atomic_set(&pHddCtx->isRestartInProgress, 1);
15306 /* Cleanup */
15307 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15308 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015309 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015310 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15311 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015312 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015313
15314}
15315
15316/**---------------------------------------------------------------------------
15317 *
15318 * \brief wlan_hdd_framework_restart
15319 *
15320 * This function uses a cfg80211 API to start a framework initiated WLAN
15321 * driver module unload/load.
15322 *
15323 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15324 *
15325 *
15326 * \param - pHddCtx
15327 *
15328 * \return - VOS_STATUS_SUCCESS: Success
15329 * VOS_STATUS_E_EMPTY: Adapter is Empty
15330 * VOS_STATUS_E_NOMEM: No memory
15331
15332 * --------------------------------------------------------------------------*/
15333
15334static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15335{
15336 VOS_STATUS status = VOS_STATUS_SUCCESS;
15337 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015338 int len = (sizeof (struct ieee80211_mgmt));
15339 struct ieee80211_mgmt *mgmt = NULL;
15340
15341 /* Prepare the DEAUTH managment frame with reason code */
15342 mgmt = kzalloc(len, GFP_KERNEL);
15343 if(mgmt == NULL)
15344 {
15345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15346 "%s: memory allocation failed (%d bytes)", __func__, len);
15347 return VOS_STATUS_E_NOMEM;
15348 }
15349 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015350
15351 /* Iterate over all adapters/devices */
15352 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015353 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15354 {
15355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015356 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015357 goto end;
15358 }
15359
Jeff Johnsone7245742012-09-05 17:12:55 -070015360 do
15361 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015362 if(pAdapterNode->pAdapter &&
15363 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015364 {
15365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15366 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15367 pAdapterNode->pAdapter->dev->name,
15368 pAdapterNode->pAdapter->device_mode,
15369 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015370 /*
15371 * CFG80211 event to restart the driver
15372 *
15373 * 'cfg80211_send_unprot_deauth' sends a
15374 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15375 * of SME(Linux Kernel) state machine.
15376 *
15377 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15378 * the driver.
15379 *
15380 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015381
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15383 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15384#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015385 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015386#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015387 }
15388 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15389 pAdapterNode = pNext;
15390 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15391
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015392 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015393 /* Free the allocated management frame */
15394 kfree(mgmt);
15395
Jeff Johnsone7245742012-09-05 17:12:55 -070015396 /* Retry until we unload or reach max count */
15397 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15398 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15399
15400 return status;
15401
15402}
15403/**---------------------------------------------------------------------------
15404 *
15405 * \brief wlan_hdd_restart_timer_cb
15406 *
15407 * Restart timer callback. An internal function.
15408 *
15409 * \param - User data:
15410 *
15411 * \return - None
15412 *
15413 * --------------------------------------------------------------------------*/
15414
15415void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15416{
15417 hdd_context_t *pHddCtx = usrDataForCallback;
15418 wlan_hdd_framework_restart(pHddCtx);
15419 return;
15420
15421}
15422
15423
15424/**---------------------------------------------------------------------------
15425 *
15426 * \brief wlan_hdd_restart_driver
15427 *
15428 * This function sends an event to supplicant to restart the WLAN driver.
15429 *
15430 * This function is called from vos_wlanRestart.
15431 *
15432 * \param - pHddCtx
15433 *
15434 * \return - VOS_STATUS_SUCCESS: Success
15435 * VOS_STATUS_E_EMPTY: Adapter is Empty
15436 * VOS_STATUS_E_ALREADY: Request already in progress
15437
15438 * --------------------------------------------------------------------------*/
15439VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15440{
15441 VOS_STATUS status = VOS_STATUS_SUCCESS;
15442
15443 /* A tight check to make sure reentrancy */
15444 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15445 {
Mihir Shetefd528652014-06-23 19:07:50 +053015446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015447 "%s: WLAN restart is already in progress", __func__);
15448
15449 return VOS_STATUS_E_ALREADY;
15450 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015451 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015452#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015453 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015454#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015455
Jeff Johnsone7245742012-09-05 17:12:55 -070015456 return status;
15457}
15458
Bhargav Shahd0715912015-10-01 18:17:37 +053015459/**
15460 * hdd_get_total_sessions() - provide total number of active sessions
15461 * @pHddCtx: Valid Global HDD context pointer
15462 *
15463 * This function iterates through pAdaptors and find the number of all active
15464 * sessions. This active sessions includes connected sta, p2p client and number
15465 * of client connected to sap/p2p go.
15466 *
15467 * Return: Total number of active sessions.
15468 */
15469v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15470{
15471 v_U8_t active_session = 0;
15472 hdd_station_ctx_t *pHddStaCtx;
15473 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15474 hdd_adapter_t *pAdapter;
15475 VOS_STATUS status;
15476
15477 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15478 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15479 pAdapter = pAdapterNode->pAdapter;
15480 switch (pAdapter->device_mode) {
15481 case VOS_STA_MODE:
15482 case VOS_P2P_CLIENT_MODE:
15483 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15484 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15485 active_session += 1;
15486 break;
15487 case VOS_STA_SAP_MODE:
15488 case VOS_P2P_GO_MODE:
15489 active_session += hdd_softap_get_connected_sta(pAdapter);
15490 break;
15491 default:
15492 break;
15493 }
15494
15495 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15496 pAdapterNode = pNext;
15497 }
15498
15499 return active_session;
15500}
15501
15502/**
15503 * hdd_set_delack_value() - Set delack value
15504 * @pHddCtx: Valid Global HDD context pointer
15505 * @next_rx_level: Value to set for delack
15506 *
15507 * This function compare present value and next value of delack. If the both
15508 * are diffrent then it sets next value .
15509 *
15510 * Return: void.
15511 */
15512void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15513{
15514 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015515 struct wlan_rx_tp_data rx_tp_data = {0};
15516
Bhargav Shahd0715912015-10-01 18:17:37 +053015517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15518 "%s: TCP DELACK trigger level %d",
15519 __func__, next_rx_level);
15520 mutex_lock(&pHddCtx->cur_rx_level_lock);
15521 pHddCtx->cur_rx_level = next_rx_level;
15522 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015523
15524 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15525 rx_tp_data.level = next_rx_level;
15526
15527 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15528 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015529 }
15530}
15531
15532/**
15533 * hdd_set_default_stop_delack_timer() - Start delack timer
15534 * @pHddCtx: Valid Global HDD context pointer
15535 *
15536 * This function stop delack timer and set delack value to default..
15537 *
15538 * Return: void.
15539 */
15540
15541void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15542{
15543 if (VOS_TIMER_STATE_RUNNING !=
15544 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15546 "%s: Can not stop timer", __func__);
15547 return;
15548 }
15549
15550 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015551 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015552}
15553
15554/**
15555 * hdd_start_delack_timer() - Start delack timer
15556 * @pHddCtx: Valid Global HDD context pointer
15557 *
15558 * This function starts the delack timer for tcpDelAckComputeInterval time
15559 * interval.The default timer value is 2 second.
15560 *
15561 * Return: void.
15562 */
15563void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15564{
15565 if (VOS_TIMER_STATE_RUNNING ==
15566 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15568 "%s: Timer is already running", __func__);
15569 return;
15570 }
15571
15572 vos_timer_start(&pHddCtx->delack_timer,
15573 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15574}
15575
15576/**
15577 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15578 * @pHddCtx: Valid Global HDD context pointer
15579 *
15580 * This function updates the prev_rx_packets count from the corresponding
15581 * pAdapter states. This prev_rx_packets will diffed with the packet count
15582 * at the end of delack timer. That can give number of RX packet is spacific
15583 * time.
15584 *
15585 * Return: void.
15586 */
15587void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15588{
15589 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15590 hdd_adapter_t *pAdapter;
15591 VOS_STATUS status;
15592
15593 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15594 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15595 pAdapter = pAdapterNode->pAdapter;
15596 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15597 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15598 pAdapterNode = pNext;
15599 }
15600}
15601
15602/**
15603 * hdd_manage_delack_timer() - start\stop delack timer
15604 * @pHddCtx: Valid Global HDD context pointer
15605 *
15606 * This function check the number of concerent session present, it starts the
15607 * delack timer if only one session is present.
15608 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15609 *
15610 * Return: void.
15611 */
15612void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15613{
15614 uint8_t sessions;
15615
15616 if (!pHddCtx->cfg_ini->enable_delack) {
15617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15618 "%s: TCP DELACK is not enabled", __func__);
15619 return;
15620 }
15621
15622 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15623 if (pHddCtx->mode != 0) {
15624 hdd_set_default_stop_delack_timer(pHddCtx);
15625 return;
15626 }
15627
15628 sessions = hdd_get_total_sessions(pHddCtx);
15629 if (sessions == 1) {
15630 hdd_update_prev_rx_packet_count(pHddCtx);
15631 hdd_start_delack_timer(pHddCtx);
15632 } else {
15633 hdd_set_default_stop_delack_timer(pHddCtx);
15634 }
15635}
15636
Mihir Shetee1093ba2014-01-21 20:13:32 +053015637/**---------------------------------------------------------------------------
15638 *
15639 * \brief wlan_hdd_init_channels
15640 *
15641 * This function is used to initialize the channel list in CSR
15642 *
15643 * This function is called from hdd_wlan_startup
15644 *
15645 * \param - pHddCtx: HDD context
15646 *
15647 * \return - VOS_STATUS_SUCCESS: Success
15648 * VOS_STATUS_E_FAULT: Failure reported by SME
15649
15650 * --------------------------------------------------------------------------*/
15651static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15652{
15653 eHalStatus status;
15654
15655 status = sme_InitChannels(pHddCtx->hHal);
15656 if (HAL_STATUS_SUCCESS(status))
15657 {
15658 return VOS_STATUS_SUCCESS;
15659 }
15660 else
15661 {
15662 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15663 __func__, status);
15664 return VOS_STATUS_E_FAULT;
15665 }
15666}
15667
Mihir Shete04206452014-11-20 17:50:58 +053015668#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015669VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015670{
15671 eHalStatus status;
15672
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015673 if (init == INIT && init_by_reg_core_user) {
15674 init_by_reg_core_user = false;
15675 pr_info("driver regulatory hint is not required");
15676
15677 return VOS_STATUS_SUCCESS;
15678 }
15679
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015680 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015681 if (HAL_STATUS_SUCCESS(status))
15682 {
15683 return VOS_STATUS_SUCCESS;
15684 }
15685 else
15686 {
15687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15688 __func__, status);
15689 return VOS_STATUS_E_FAULT;
15690 }
15691}
Mihir Shete04206452014-11-20 17:50:58 +053015692#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015693/*
15694 * API to find if there is any STA or P2P-Client is connected
15695 */
15696VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15697{
15698 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15699}
Jeff Johnsone7245742012-09-05 17:12:55 -070015700
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015701
15702/*
15703 * API to find if the firmware will send logs using DXE channel
15704 */
15705v_U8_t hdd_is_fw_logging_enabled(void)
15706{
15707 hdd_context_t *pHddCtx;
15708
15709 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15710 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15711
Sachin Ahuja084313e2015-05-21 17:57:10 +053015712 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015713}
15714
Agarwal Ashish57e84372014-12-05 18:26:53 +053015715/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015716 * API to find if the firmware will send trace logs using DXE channel
15717 */
15718v_U8_t hdd_is_fw_ev_logging_enabled(void)
15719{
15720 hdd_context_t *pHddCtx;
15721
15722 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15723 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15724
15725 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15726}
15727/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015728 * API to find if there is any session connected
15729 */
15730VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15731{
15732 return sme_is_any_session_connected(pHddCtx->hHal);
15733}
15734
15735
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015736int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15737{
15738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15739 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015740 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015741 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015742
15743 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015744 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015745 if (pScanInfo->mScanPending)
15746 {
c_hpothua3d45d52015-01-05 14:11:17 +053015747 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15748 eCSR_SCAN_ABORT_DEFAULT);
15749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15750 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015751
c_hpothua3d45d52015-01-05 14:11:17 +053015752 /* If there is active scan command lets wait for the completion else
15753 * there is no need to wait as scan command might be in the SME pending
15754 * command list.
15755 */
15756 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15757 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015758 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015759 &pScanInfo->abortscan_event_var,
15760 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015761 if (0 >= status)
15762 {
15763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015764 "%s: Timeout or Interrupt occurred while waiting for abort"
15765 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015766 return -ETIMEDOUT;
15767 }
15768 }
15769 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15770 {
15771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15772 FL("hdd_abort_mac_scan failed"));
15773 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015774 }
15775 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015776 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015777}
15778
Abhishek Singh7d624e12015-11-30 14:29:27 +053015779/**
15780 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15781 * user space
15782 * @frame_ind: Management frame data to be informed.
15783 *
15784 * This function is used to indicate management frame to
15785 * user space
15786 *
15787 * Return: None
15788 *
15789 */
15790void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15791{
15792 hdd_context_t *hdd_ctx = NULL;
15793 hdd_adapter_t *adapter = NULL;
15794 v_CONTEXT_t vos_context = NULL;
15795
15796 /* Get the global VOSS context.*/
15797 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15798 if (!vos_context) {
15799 hddLog(LOGE, FL("Global VOS context is Null"));
15800 return;
15801 }
15802 /* Get the HDD context.*/
15803 hdd_ctx =
15804 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15805
15806 if (0 != wlan_hdd_validate_context(hdd_ctx))
15807 {
15808 return;
15809 }
15810 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15811 frame_ind->sessionId);
15812
15813 if ((NULL != adapter) &&
15814 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15815 __hdd_indicate_mgmt_frame(adapter,
15816 frame_ind->frameLen,
15817 frame_ind->frameBuf,
15818 frame_ind->frameType,
15819 frame_ind->rxChan,
15820 frame_ind->rxRssi);
15821 return;
15822
15823}
15824
c_hpothu225aa7c2014-10-22 17:45:13 +053015825VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15826{
15827 hdd_adapter_t *pAdapter;
15828 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15829 VOS_STATUS vosStatus;
15830
15831 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15832 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15833 {
15834 pAdapter = pAdapterNode->pAdapter;
15835 if (NULL != pAdapter)
15836 {
15837 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15838 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15839 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15840 {
15841 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15842 pAdapter->device_mode);
15843 if (VOS_STATUS_SUCCESS !=
15844 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15845 {
15846 hddLog(LOGE, FL("failed to abort ROC"));
15847 return VOS_STATUS_E_FAILURE;
15848 }
15849 }
15850 }
15851 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15852 pAdapterNode = pNext;
15853 }
15854 return VOS_STATUS_SUCCESS;
15855}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015856
Mihir Shete0be28772015-02-17 18:42:14 +053015857hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15858{
15859 hdd_adapter_t *pAdapter;
15860 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15861 hdd_cfg80211_state_t *cfgState;
15862 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15863 VOS_STATUS vosStatus;
15864
15865 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15866 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15867 {
15868 pAdapter = pAdapterNode->pAdapter;
15869 if (NULL != pAdapter)
15870 {
15871 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15872 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15873 if (pRemainChanCtx)
15874 break;
15875 }
15876 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15877 pAdapterNode = pNext;
15878 }
15879 return pRemainChanCtx;
15880}
15881
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015882/**
15883 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15884 *
15885 * @pHddCtx: HDD context within host driver
15886 * @dfsScanMode: dfsScanMode passed from ioctl
15887 *
15888 */
15889
15890VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15891 tANI_U8 dfsScanMode)
15892{
15893 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15894 hdd_adapter_t *pAdapter;
15895 VOS_STATUS vosStatus;
15896 hdd_station_ctx_t *pHddStaCtx;
15897 eHalStatus status = eHAL_STATUS_SUCCESS;
15898
15899 if(!pHddCtx)
15900 {
15901 hddLog(LOGE, FL("HDD context is Null"));
15902 return eHAL_STATUS_FAILURE;
15903 }
15904
15905 if (pHddCtx->scan_info.mScanPending)
15906 {
15907 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15908 pHddCtx->scan_info.sessionId);
15909 hdd_abort_mac_scan(pHddCtx,
15910 pHddCtx->scan_info.sessionId,
15911 eCSR_SCAN_ABORT_DEFAULT);
15912 }
15913
15914 if (!dfsScanMode)
15915 {
15916 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15917 while ((NULL != pAdapterNode) &&
15918 (VOS_STATUS_SUCCESS == vosStatus))
15919 {
15920 pAdapter = pAdapterNode->pAdapter;
15921
15922 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15923 {
15924 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15925
15926 if(!pHddStaCtx)
15927 {
15928 hddLog(LOGE, FL("HDD STA context is Null"));
15929 return eHAL_STATUS_FAILURE;
15930 }
15931
15932 /* if STA is already connected on DFS channel,
15933 disconnect immediately*/
15934 if (hdd_connIsConnected(pHddStaCtx) &&
15935 (NV_CHANNEL_DFS ==
15936 vos_nv_getChannelEnabledState(
15937 pHddStaCtx->conn_info.operationChannel)))
15938 {
15939 status = sme_RoamDisconnect(pHddCtx->hHal,
15940 pAdapter->sessionId,
15941 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15942 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15943 "sme_RoamDisconnect returned with status: %d"
15944 "for sessionid: %d"), pHddStaCtx->conn_info.
15945 operationChannel, status, pAdapter->sessionId);
15946 }
15947 }
15948
15949 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15950 &pNext);
15951 pAdapterNode = pNext;
15952 }
15953 }
15954
15955 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15956 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15957 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15958
15959 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15960 if (!HAL_STATUS_SUCCESS(status))
15961 {
15962 hddLog(LOGE,
15963 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15964 return status;
15965 }
15966
15967 return status;
15968}
15969
Nirav Shah7e3c8132015-06-22 23:51:42 +053015970static int hdd_log2_ceil(unsigned value)
15971{
15972 /* need to switch to unsigned math so that negative values
15973 * will right-shift towards 0 instead of -1
15974 */
15975 unsigned tmp = value;
15976 int log2 = -1;
15977
15978 if (value == 0)
15979 return 0;
15980
15981 while (tmp) {
15982 log2++;
15983 tmp >>= 1;
15984 }
15985 if (1U << log2 != value)
15986 log2++;
15987
15988 return log2;
15989}
15990
15991/**
15992 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15993 * @pAdapter: adapter handle
15994 *
15995 * Return: vos status
15996 */
15997VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15998{
15999 int hash_elem, log2, i;
16000
16001 spin_lock_bh( &pAdapter->sta_hash_lock);
16002 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16003 spin_unlock_bh( &pAdapter->sta_hash_lock);
16004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16005 "%s: hash already attached for session id %d",
16006 __func__, pAdapter->sessionId);
16007 return VOS_STATUS_SUCCESS;
16008 }
16009 spin_unlock_bh( &pAdapter->sta_hash_lock);
16010
16011 hash_elem = WLAN_MAX_STA_COUNT;
16012 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16013 log2 = hdd_log2_ceil(hash_elem);
16014 hash_elem = 1 << log2;
16015
16016 pAdapter->sta_id_hash.mask = hash_elem - 1;
16017 pAdapter->sta_id_hash.idx_bits = log2;
16018 pAdapter->sta_id_hash.bins =
16019 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16020 if (!pAdapter->sta_id_hash.bins) {
16021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16022 "%s: malloc failed for session %d",
16023 __func__, pAdapter->sessionId);
16024 return VOS_STATUS_E_NOMEM;
16025 }
16026
16027 for (i = 0; i < hash_elem; i++)
16028 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16029
16030 spin_lock_bh( &pAdapter->sta_hash_lock);
16031 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16032 spin_unlock_bh( &pAdapter->sta_hash_lock);
16033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16034 "%s: Station ID Hash attached for session id %d",
16035 __func__, pAdapter->sessionId);
16036
16037 return VOS_STATUS_SUCCESS;
16038}
16039
16040/**
16041 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16042 * @pAdapter: adapter handle
16043 *
16044 * Return: vos status
16045 */
16046VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16047{
16048 int hash_elem, i;
16049 v_SIZE_t size;
16050
16051 spin_lock_bh( &pAdapter->sta_hash_lock);
16052 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16053 spin_unlock_bh( &pAdapter->sta_hash_lock);
16054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16055 "%s: hash not initialized for session id %d",
16056 __func__, pAdapter->sessionId);
16057 return VOS_STATUS_SUCCESS;
16058 }
16059
16060 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16061 spin_unlock_bh( &pAdapter->sta_hash_lock);
16062
16063 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16064
16065 /* free all station info*/
16066 for (i = 0; i < hash_elem; i++) {
16067 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16068 if (size != 0) {
16069 VOS_STATUS status;
16070 hdd_staid_hash_node_t *sta_info_node = NULL;
16071 hdd_staid_hash_node_t *next_node = NULL;
16072 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16073 (hdd_list_node_t**) &sta_info_node );
16074
16075 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16076 {
16077 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16078 &sta_info_node->node);
16079 vos_mem_free(sta_info_node);
16080
16081 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16082 (hdd_list_node_t*)sta_info_node,
16083 (hdd_list_node_t**)&next_node);
16084 sta_info_node = next_node;
16085 }
16086 }
16087 }
16088
16089 vos_mem_free(pAdapter->sta_id_hash.bins);
16090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16091 "%s: Station ID Hash detached for session id %d",
16092 __func__, pAdapter->sessionId);
16093 return VOS_STATUS_SUCCESS;
16094}
16095
16096/**
16097 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16098 * @pAdapter: adapter handle
16099 * @mac_addr_in: input mac address
16100 *
16101 * Return: index derived from mac address
16102 */
16103int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16104 v_MACADDR_t *mac_addr_in)
16105{
16106 uint16 index;
16107 struct hdd_align_mac_addr_t * mac_addr =
16108 (struct hdd_align_mac_addr_t *)mac_addr_in;
16109
16110 index = mac_addr->bytes_ab ^
16111 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16112 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16113 index &= pAdapter->sta_id_hash.mask;
16114 return index;
16115}
16116
16117/**
16118 * hdd_sta_id_hash_add_entry() - add entry in hash
16119 * @pAdapter: adapter handle
16120 * @sta_id: station id
16121 * @mac_addr: mac address
16122 *
16123 * Return: vos status
16124 */
16125VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16126 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16127{
16128 uint16 index;
16129 hdd_staid_hash_node_t *sta_info_node = NULL;
16130
Nirav Shah7e3c8132015-06-22 23:51:42 +053016131 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16132 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16133 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16135 "%s: malloc failed", __func__);
16136 return VOS_STATUS_E_NOMEM;
16137 }
16138
16139 sta_info_node->sta_id = sta_id;
16140 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16141
Nirav Shah303ed5c2015-08-24 10:29:25 +053016142 spin_lock_bh( &pAdapter->sta_hash_lock);
16143 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16144 spin_unlock_bh( &pAdapter->sta_hash_lock);
16145 vos_mem_free(sta_info_node);
16146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16147 "%s: hash is not initialized for session id %d",
16148 __func__, pAdapter->sessionId);
16149 return VOS_STATUS_E_FAILURE;
16150 }
16151
Nirav Shah7e3c8132015-06-22 23:51:42 +053016152 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16153 (hdd_list_node_t*) sta_info_node );
16154 spin_unlock_bh( &pAdapter->sta_hash_lock);
16155 return VOS_STATUS_SUCCESS;
16156}
16157
16158/**
16159 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16160 * @pAdapter: adapter handle
16161 * @sta_id: station id
16162 * @mac_addr: mac address
16163 *
16164 * Return: vos status
16165 */
16166VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16167 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16168{
16169 uint16 index;
16170 VOS_STATUS status;
16171 hdd_staid_hash_node_t *sta_info_node = NULL;
16172 hdd_staid_hash_node_t *next_node = NULL;
16173
16174 spin_lock_bh( &pAdapter->sta_hash_lock);
16175 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16176 spin_unlock_bh( &pAdapter->sta_hash_lock);
16177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16178 "%s: hash is not initialized for session id %d",
16179 __func__, pAdapter->sessionId);
16180 return VOS_STATUS_E_FAILURE;
16181 }
16182
16183 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16184 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16185 (hdd_list_node_t**) &sta_info_node );
16186
16187 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16188 {
16189 if (sta_info_node->sta_id == sta_id) {
16190 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16191 &sta_info_node->node);
16192 vos_mem_free(sta_info_node);
16193 break;
16194 }
16195 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16196 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16197 sta_info_node = next_node;
16198 }
16199 spin_unlock_bh( &pAdapter->sta_hash_lock);
16200 return status;
16201}
16202
16203/**
16204 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16205 * @pAdapter: adapter handle
16206 * @mac_addr_in: mac address
16207 *
16208 * Return: station id
16209 */
16210int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16211 v_MACADDR_t *mac_addr_in)
16212{
16213 uint8 is_found = 0;
16214 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16215 uint16 index;
16216 VOS_STATUS status;
16217 hdd_staid_hash_node_t *sta_info_node = NULL;
16218 hdd_staid_hash_node_t *next_node = NULL;
16219
16220 spin_lock_bh( &pAdapter->sta_hash_lock);
16221 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16222 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016223 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016224 FL("hash is not initialized for session id %d"),
16225 pAdapter->sessionId);
16226 return HDD_WLAN_INVALID_STA_ID;
16227 }
16228
16229 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16230 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16231 (hdd_list_node_t**) &sta_info_node );
16232
16233 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16234 {
16235 if (vos_mem_compare(&sta_info_node->mac_addr,
16236 mac_addr_in, sizeof(v_MACADDR_t))) {
16237 is_found = 1;
16238 sta_id = sta_info_node->sta_id;
16239 break;
16240 }
16241 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16242 (hdd_list_node_t*)sta_info_node,
16243 (hdd_list_node_t**)&next_node);
16244 sta_info_node = next_node;
16245 }
16246 spin_unlock_bh( &pAdapter->sta_hash_lock);
16247 return sta_id;
16248}
16249
c_manjeecfd1efb2015-09-25 19:32:34 +053016250/*FW memory dump feature*/
16251/**
16252 * This structure hold information about the /proc file
16253 *
16254 */
16255static struct proc_dir_entry *proc_file, *proc_dir;
16256
16257/**
16258 * memdump_read() - perform read operation in memory dump proc file
16259 *
16260 * @file - handle for the proc file.
16261 * @buf - pointer to user space buffer.
16262 * @count - number of bytes to be read.
16263 * @pos - offset in the from buffer.
16264 *
16265 * This function performs read operation for the memory dump proc file.
16266 *
16267 * Return: number of bytes read on success, error code otherwise.
16268 */
16269static ssize_t memdump_read(struct file *file, char __user *buf,
16270 size_t count, loff_t *pos)
16271{
16272 int status;
16273 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16274 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016275 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016276 ENTER();
16277
16278 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16279 status = wlan_hdd_validate_context(hdd_ctx);
16280 if (0 != status) {
16281 return -EINVAL;
16282 }
16283
16284 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16285 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16286 return -EINVAL;
16287 }
16288
16289 /* run fs_read_handler in an atomic context*/
16290 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016291 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16292 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016293 {
16294 /*Free the fwr mem dump buffer */
16295 wlan_free_fwr_mem_dump_buffer();
16296 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016297 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016298 }
16299 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16300 vos_ssr_unprotect(__func__);
16301 EXIT();
16302 return ret_count;
16303}
16304
16305/**
16306 * struct memdump_fops - file operations for memory dump feature
16307 * @read - read function for memory dump operation.
16308 *
16309 * This structure initialize the file operation handle for memory
16310 * dump feature
16311 */
16312static const struct file_operations memdump_fops = {
16313 read: memdump_read
16314};
16315
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016316struct fw_mem_dump_priv {
16317 uint32_t status;
16318};
16319
c_manjeecfd1efb2015-09-25 19:32:34 +053016320/*
16321* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16322* To be passed by HDD to WDA and called upon receiving of response
16323* from firmware
16324* @fwMemDumpReqContext : memory dump request context
16325* @dump_rsp : dump response from HAL
16326* Returns none
16327*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016328void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016329 tAniFwrDumpRsp *dump_rsp)
16330{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016331 struct hdd_request *request;
16332 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016333
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016334 request = hdd_request_get(context);
16335 if (!request) {
16336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16337 return;
16338 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016339
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016340 ENTER();
16341
16342 priv = hdd_request_priv(request);
16343 priv->status = dump_rsp->dump_status;
16344
16345 /* report the status to requesting function and free mem.*/
16346 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16347 hddLog(LOGE, FL("fw dump request declined by fwr"));
16348 //set the request completion variable
16349 hdd_request_complete(request);
16350 //Free the allocated fwr dump
16351 wlan_free_fwr_mem_dump_buffer();
16352 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16353 } else {
16354 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16355 /* register the HDD callback which will be called by SVC */
16356 wlan_set_svc_fw_mem_dump_req_cb(
16357 (void*)wlan_hdd_fw_mem_dump_req_cb,
16358 context);
16359 }
16360
16361 hdd_request_put(request);
16362
16363 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016364}
16365
16366/**
16367 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16368 *
16369 * This function removes file/dir under proc file system that was
16370 * processing firmware memory dump
16371 *
16372 * Return: None
16373 */
16374static void memdump_procfs_remove(void)
16375{
16376 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16377 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16378 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16379 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16380 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16381}
16382
16383/**
16384 * memdump_procfs_init() - Initialize procfs for memory dump
16385 *
16386 * @vos_ctx - Global vos context.
16387 *
16388 * This function create file under proc file system to be used later for
16389 * processing firmware memory dump
16390 *
16391 * Return: 0 on success, error code otherwise.
16392 */
16393static int memdump_procfs_init(void *vos_ctx)
16394{
16395 hdd_context_t *hdd_ctx;
16396
16397 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16398 if (!hdd_ctx) {
16399 hddLog(LOGE , FL("Invalid HDD context"));
16400 return -EINVAL;
16401 }
16402
16403 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16404 if (proc_dir == NULL) {
16405 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16406 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16407 PROCFS_MEMDUMP_DIR);
16408 return -ENOMEM;
16409 }
16410
16411 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16412 S_IRUSR | S_IWUSR, proc_dir,
16413 &memdump_fops, hdd_ctx);
16414 if (proc_file == NULL) {
16415 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16416 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16417 PROCFS_MEMDUMP_NAME);
16418 return -ENOMEM;
16419 }
16420
16421 hddLog(LOG1 , FL("/proc/%s/%s created"),
16422 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16423
16424 return 0;
16425}
16426
16427/**
16428 * memdump_init() - Initialization function for memory dump feature
16429 *
16430 * This function creates proc file for memdump feature and registers
16431 * HDD callback function with SME.
16432 *
16433 * Return - 0 on success, error otherwise
16434 */
16435int memdump_init(void)
16436{
16437 hdd_context_t *hdd_ctx;
16438 void *vos_ctx;
16439 int status = 0;
16440
16441 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16442 if (!vos_ctx) {
16443 hddLog(LOGE, FL("Invalid VOS context"));
16444 return -EINVAL;
16445 }
16446
16447 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16448 if (!hdd_ctx) {
16449 hddLog(LOGE , FL("Invalid HDD context"));
16450 return -EINVAL;
16451 }
16452
16453 status = memdump_procfs_init(vos_ctx);
16454 if (status) {
16455 hddLog(LOGE , FL("Failed to create proc file"));
16456 return status;
16457 }
16458
16459 return 0;
16460}
16461
16462/**
16463 * memdump_deinit() - De initialize memdump feature
16464 *
16465 * This function removes proc file created for memdump feature.
16466 *
16467 * Return: None
16468 */
16469int memdump_deinit(void)
16470{
16471 hdd_context_t *hdd_ctx;
16472 void *vos_ctx;
16473
16474 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16475 if (!vos_ctx) {
16476 hddLog(LOGE, FL("Invalid VOS context"));
16477 return -EINVAL;
16478 }
16479
16480 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16481 if(!hdd_ctx) {
16482 hddLog(LOGE , FL("Invalid HDD context"));
16483 return -EINVAL;
16484 }
16485
16486 memdump_procfs_remove();
16487 return 0;
16488}
16489
16490/**
16491 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16492 * Return: HAL status
16493 */
16494
16495int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16496{
16497 tAniFwrDumpReq fw_mem_dump_req={0};
16498 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016499 int ret=0, dump_status;
16500 void *cookie;
16501 struct hdd_request *request;
16502 struct fw_mem_dump_priv *priv;
16503 static const struct hdd_request_params params = {
16504 .priv_size = sizeof(*priv),
16505 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16506 };
16507
c_manjeecfd1efb2015-09-25 19:32:34 +053016508 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016509
c_manjeecfd1efb2015-09-25 19:32:34 +053016510 /*Check whether a dump request is already going on
16511 *Caution this function will free previously held memory if new dump request is allowed*/
16512 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16513 hddLog(LOGE, FL("Fw memdump already in progress"));
16514 return -EBUSY;
16515 }
16516 //Allocate memory for fw mem dump buffer
16517 ret = wlan_fwr_mem_dump_buffer_allocation();
16518 if(ret == -EFAULT)
16519 {
16520 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16521 return ret;
16522 }
16523 if (0 != ret) {
16524 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16525 return -ENOMEM;
16526 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016527
16528 request = hdd_request_alloc(&params);
16529 if (!request) {
16530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16531 return VOS_STATUS_E_NOMEM;
16532 }
16533 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016534
c_manjeecfd1efb2015-09-25 19:32:34 +053016535 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016536 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016537 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16538 if(eHAL_STATUS_SUCCESS != status)
16539 {
16540 hddLog(VOS_TRACE_LEVEL_ERROR,
16541 "%s: fw_mem_dump_req failed ", __func__);
16542 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016543 ret = -EFAULT;
16544 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016545 }
c_manjeef1495642015-10-13 18:35:01 +053016546 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016547 ret = hdd_request_wait_for_response(request);
16548 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016549 {
16550 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016551 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016552 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016553 }else {
16554 priv = hdd_request_priv(request);
16555 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016556 }
16557cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016558 hdd_request_put(request);
16559 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016560 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016561
c_manjeef1495642015-10-13 18:35:01 +053016562 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016563 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016564}
16565
16566/**
16567 * HDD callback which will be called by SVC to indicate mem dump completion.
16568 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016569void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016570{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016571 struct hdd_request *request;
16572 struct fw_mem_dump_priv *priv;
16573
16574 request = hdd_request_get(context);
16575 if (!request) {
16576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16577 return;
16578 }
16579
16580 priv = hdd_request_priv(request);
16581 priv->status = true;
16582
16583 hdd_request_complete(request);
16584 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016585}
16586
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016587void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16588{
16589 if (NULL == pAdapter)
16590 {
16591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16592 return;
16593 }
16594 init_completion(&pAdapter->session_open_comp_var);
16595 init_completion(&pAdapter->session_close_comp_var);
16596 init_completion(&pAdapter->disconnect_comp_var);
16597 init_completion(&pAdapter->linkup_event_var);
16598 init_completion(&pAdapter->cancel_rem_on_chan_var);
16599 init_completion(&pAdapter->rem_on_chan_ready_event);
16600 init_completion(&pAdapter->pno_comp_var);
16601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16602 init_completion(&pAdapter->offchannel_tx_event);
16603#endif
16604 init_completion(&pAdapter->tx_action_cnf_event);
16605#ifdef FEATURE_WLAN_TDLS
16606 init_completion(&pAdapter->tdls_add_station_comp);
16607 init_completion(&pAdapter->tdls_del_station_comp);
16608 init_completion(&pAdapter->tdls_mgmt_comp);
16609 init_completion(&pAdapter->tdls_link_establish_req_comp);
16610#endif
16611
16612#ifdef WLAN_FEATURE_RMC
16613 init_completion(&pAdapter->ibss_peer_info_comp);
16614#endif /* WLAN_FEATURE_RMC */
16615 init_completion(&pAdapter->ula_complete);
16616 init_completion(&pAdapter->change_country_code);
16617
16618#ifdef FEATURE_WLAN_BATCH_SCAN
16619 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16620 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16621#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016622 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016623
16624 return;
16625}
c_manjeecfd1efb2015-09-25 19:32:34 +053016626
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016627#ifdef MDNS_OFFLOAD
16628
16629/**
16630 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16631 * @padapter: holds adapter
16632 * @status: response status
16633 *
16634 * Return - None
16635 */
16636void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16637{
16638 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16639
16640 ENTER();
16641
16642 if (NULL == adapter)
16643 {
16644 hddLog(VOS_TRACE_LEVEL_ERROR,
16645 "%s: adapter is NULL",__func__);
16646 return;
16647 }
16648
16649 adapter->mdns_status.mdns_enable_status = status;
16650 vos_event_set(&adapter->mdns_status.vos_event);
16651 return;
16652}
16653
16654/**
16655 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16656 * @padapter: holds adapter
16657 * @status: responce status
16658 *
16659 * Return - None
16660 */
16661void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16662{
16663 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16664
16665 ENTER();
16666
16667 if (NULL == adapter)
16668 {
16669 hddLog(VOS_TRACE_LEVEL_ERROR,
16670 "%s: adapter is NULL",__func__);
16671 return;
16672 }
16673
16674 adapter->mdns_status.mdns_fqdn_status = status;
16675 return;
16676}
16677
16678/**
16679 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16680 * @padapter: holds adapter
16681 * @status: responce status
16682 *
16683 * Return - None
16684 */
16685void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16686{
16687 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16688
16689 ENTER();
16690
16691 if (NULL == adapter)
16692 {
16693 hddLog(VOS_TRACE_LEVEL_ERROR,
16694 "%s: adapter is NULL",__func__);
16695 return;
16696 }
16697
16698 adapter->mdns_status.mdns_resp_status = status;
16699 return;
16700}
16701
16702/**
16703 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16704 * @response: Pointer to a struct hdd_mdns_resp_info
16705 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16706 *
16707 * This function will pack the whole domain name without compression. It will
16708 * add the leading len for each field and add zero length octet to terminate
16709 * the domain name.
16710 *
16711 * Return: Return boolean. TRUE for success, FALSE for fail.
16712 */
16713static bool
16714wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16715 sir_mdns_resp_info resp_info)
16716{
16717 uint8_t num;
16718 uint16_t idx;
16719 uint8_t len = 0;
16720
16721 if ((response == NULL) || (response->data == NULL) ||
16722 (response->offset == NULL)) {
16723 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16724 return FALSE;
16725 }
16726
16727 if ((resp_info == NULL) ||
16728 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16729 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16730 return FALSE;
16731 }
16732
16733 for (num = 0; num < response->num_entries; num++) {
16734 response->offset[num] =
16735 resp_info->resp_len + MDNS_HEADER_LEN;
16736 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16737 len = strlen((char *)&response->data[idx]);
16738 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16739 hddLog(LOGE, FL("resp_len exceeds %d!"),
16740 MAX_MDNS_RESP_LEN);
16741 return FALSE;
16742 }
16743 resp_info->resp_data[resp_info->resp_len] = len;
16744 resp_info->resp_len++;
16745 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16746 &response->data[idx], len);
16747 resp_info->resp_len += len;
16748 }
16749
16750 /* The domain name terminates with the zero length octet */
16751 if (num == response->num_entries) {
16752 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16753 hddLog(LOGE, FL("resp_len exceeds %d!"),
16754 MAX_MDNS_RESP_LEN);
16755 return FALSE;
16756 }
16757 resp_info->resp_data[resp_info->resp_len] = 0;
16758 resp_info->resp_len++;
16759 }
16760
16761 return TRUE;
16762}
16763
16764/**
16765 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16766 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16767 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16768 *
16769 * Return: None
16770 */
16771static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16772 sir_mdns_resp_info resp_info)
16773{
16774 uint8_t val_u8;
16775
16776 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16777 return;
16778 val_u8 = (value & 0xff00) >> 8;
16779 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16780 val_u8 = value & 0xff;
16781 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16782}
16783
16784/**
16785 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16786 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16787 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16788 *
16789 * Return: None
16790 */
16791static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16792 sir_mdns_resp_info resp_info)
16793{
16794 uint8_t val_u8;
16795
16796 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16797 return;
16798 val_u8 = (value & 0xff000000) >> 24;
16799 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16800 val_u8 = (value & 0xff0000) >> 16;
16801 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16802 val_u8 = (value & 0xff00) >> 8;
16803 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16804 val_u8 = value & 0xff;
16805 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16806}
16807
16808/**
16809 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16810 * @resp_type: Response type for mDNS
16811 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16812 *
16813 * This function will pack the response type, class and TTL (Time To Live).
16814 *
16815 * Return: Return boolean. TRUE for success, FALSE for fail.
16816 */
16817static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16818 sir_mdns_resp_info resp_info)
16819{
16820 uint16_t len;
16821
16822 if (resp_info == NULL) {
16823 hddLog(LOGE, FL("resp_info is NULL!"));
16824 return FALSE;
16825 }
16826
16827 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16828 if (len >= MAX_MDNS_RESP_LEN) {
16829 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16830 return FALSE;
16831 }
16832
16833 /* Fill Type, Class, TTL */
16834 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16835 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16836 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16837
16838 return TRUE;
16839}
16840
16841/**
16842 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16843 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16844 * @response_dst: The response which domain name is compressed.
16845 * @response_src: The response which domain name is matched with response_dst.
16846 * Its offset is used for data compression.
16847 * @num_matched: The number of matched entries between response_dst and
16848 * response_src
16849 *
16850 * This function will form the different fields of domain name in response_dst
16851 * if any. Then use the offset of the matched domain name in response_src to
16852 * compress the matched domain name.
16853 *
16854 * Return: Return boolean. TRUE for success, FALSE for fail.
16855 */
16856static bool
16857wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16858 struct hdd_mdns_resp_info *response_dst,
16859 struct hdd_mdns_resp_info *response_src,
16860 uint8_t num_matched)
16861{
16862 uint8_t num, num_diff;
16863 uint16_t value, idx;
16864 uint8_t len = 0;
16865
16866 if ((response_src == NULL) || (response_dst == NULL) ||
16867 (resp_info == NULL)) {
16868 hddLog(LOGE, FL("response info is NULL!"));
16869 return FALSE;
16870 }
16871
16872 if (response_dst->num_entries < num_matched) {
16873 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16874 return FALSE;
16875 }
16876
16877 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16878 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16879 return FALSE;
16880 }
16881
16882 num_diff = response_dst->num_entries - num_matched;
16883 if ((num_diff > 0) && (response_dst->data == NULL)) {
16884 hddLog(LOGE, FL("response_dst->data is NULL!"));
16885 return FALSE;
16886 }
16887
16888 /*
16889 * Handle the unmatched string at the beginning
16890 * Store the length of octets and the octets
16891 */
16892 for (num = 0; num < num_diff; num++) {
16893 response_dst->offset[num] =
16894 resp_info->resp_len + MDNS_HEADER_LEN;
16895 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16896 len = strlen((char *)&response_dst->data[idx]);
16897 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16898 hddLog(LOGE, FL("resp_len exceeds %d!"),
16899 MAX_MDNS_RESP_LEN);
16900 return FALSE;
16901 }
16902 resp_info->resp_data[resp_info->resp_len] = len;
16903 resp_info->resp_len++;
16904 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16905 &response_dst->data[idx], len);
16906 resp_info->resp_len += len;
16907 }
16908 /*
16909 * Handle the matched string from the end
16910 * Just keep the offset and mask the leading two bit
16911 */
16912 if (response_src->num_entries >= num_matched) {
16913 num_diff = response_src->num_entries - num_matched;
16914 value = response_src->offset[num_diff];
16915 if (value > 0) {
16916 value |= 0xc000;
16917 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16918 MAX_MDNS_RESP_LEN) {
16919 hddLog(LOGE, FL("resp_len exceeds %d!"),
16920 MAX_MDNS_RESP_LEN);
16921 return FALSE;
16922 }
16923 wlan_hdd_mdns_format_response_u16(value, resp_info);
16924 return TRUE;
16925 }
16926 }
16927 return FALSE;
16928}
16929
16930/**
16931 * wlan_hdd_mdns_reset_response() - Reset the response info
16932 * @response: The response which info is reset.
16933 *
16934 * Return: None
16935 */
16936static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16937{
16938 if (response == NULL)
16939 return;
16940 response->num_entries = 0;
16941 response->data = NULL;
16942 response->offset = NULL;
16943}
16944
16945/**
16946 * wlan_hdd_mdns_init_response() - Initialize the response info
16947 * @response: The response which info is initiatized.
16948 * @resp_dname: The domain name string which might be tokenized.
16949 *
16950 * This function will allocate the memory for both response->data and
16951 * response->offset. Besides, it will also tokenize the domain name to some
16952 * entries and fill response->num_entries with the num of entries.
16953 *
16954 * Return: Return boolean. TRUE for success, FALSE for fail.
16955 */
16956static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16957 uint8_t *resp_dname, char separator)
16958{
16959 uint16_t size;
16960
16961 if ((resp_dname == NULL) || (response == NULL)) {
16962 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16963 return FALSE;
16964 }
16965
16966 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16967 response->data = vos_mem_malloc(size);
16968 if (response->data) {
16969 vos_mem_zero(response->data, size);
16970 if (VOS_STATUS_SUCCESS !=
16971 hdd_string_to_string_array((char *)resp_dname,
16972 response->data,
16973 separator,
16974 &response->num_entries,
16975 MAX_NUM_FIELD_DOMAINNAME,
16976 MAX_LEN_DOMAINNAME_FIELD)) {
16977 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16978 goto err_init_resp;
16979 }
16980
16981 if ((response->num_entries > 0) &&
16982 (strlen((char *)&response->data[0]) > 0)) {
16983 size = sizeof(uint16_t) * response->num_entries;
16984 response->offset = vos_mem_malloc(size);
16985 if (response->offset) {
16986 vos_mem_zero(response->offset, size);
16987 return TRUE;
16988 }
16989 }
16990 }
16991
16992err_init_resp:
16993 if (response->data)
16994 vos_mem_free(response->data);
16995 wlan_hdd_mdns_reset_response(response);
16996 return FALSE;
16997}
16998
16999/**
17000 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
17001 * @response1: The response info is used to be compared.
17002 * @response2: The response info is used to be compared.
17003 *
17004 * This function will find the matched entries from the end.
17005 *
17006 * Return: Return the number of the matched entries.
17007 */
17008static uint8_t
17009wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
17010 struct hdd_mdns_resp_info *response2)
17011{
17012 uint8_t min, len1, i;
17013 uint16_t num1, num2;
17014 uint8_t num_matched = 0;
17015
17016 min = VOS_MIN(response1->num_entries, response2->num_entries);
17017
17018 for (i = 1; i <= min; i++) {
17019 num1 = (response1->num_entries - i);
17020 num1 *= MAX_LEN_DOMAINNAME_FIELD;
17021 num2 = (response2->num_entries - i);
17022 num2 *= MAX_LEN_DOMAINNAME_FIELD;
17023 len1 = strlen((char *)&response1->data[num1]);
17024
17025 if ((len1 == 0) ||
17026 (len1 != strlen((char *)&response2->data[num2])))
17027 break;
17028 if (memcmp(&response1->data[num1],
17029 &response2->data[num2], len1))
17030 break;
17031 else
17032 num_matched++;
17033 }
17034
17035 return num_matched;
17036}
17037
17038/**
17039 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17040 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17041 * @numlist: The number of the elements in the array matchedlist.
17042 *
17043 * Find the max number of the matched entries among the array matchedlist.
17044 *
17045 * Return: None
17046 */
17047static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17048 uint8_t numlist)
17049{
17050 int j;
17051 struct hdd_mdns_resp_matched tmp;
17052
17053 /* At least two values are used for sorting */
17054 if ((numlist < 2) || (matchedlist == NULL)) {
17055 hddLog(LOGE, FL("At least two values are used for sorting!"));
17056 return;
17057 }
17058
17059 for (j = 0; j < numlist-1; j++) {
17060 if (matchedlist[j].num_matched >
17061 matchedlist[j+1].num_matched) {
17062 vos_mem_copy(&tmp, &matchedlist[j],
17063 sizeof(struct hdd_mdns_resp_matched));
17064 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17065 sizeof(struct hdd_mdns_resp_matched));
17066 vos_mem_copy(&matchedlist[j+1], &tmp,
17067 sizeof(struct hdd_mdns_resp_matched));
17068 }
17069 }
17070}
17071
17072/**
17073 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17074 * @ini_config: Pointer to the struct hdd_config_t
17075 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17076 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17077 *
17078 * Type A response include QName, response type, class, TTL and Ipv4.
17079 *
17080 * Return: Return boolean. TRUE for success, FALSE for fail.
17081 */
17082static bool
17083wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17084 sir_mdns_resp_info resp_info,
17085 struct hdd_mdns_resp_info *resptype_a)
17086{
17087 uint16_t value;
17088 uint32_t len;
17089
17090 ENTER();
17091 if ((ini_config == NULL) || (resp_info == NULL) ||
17092 (resptype_a == NULL)) {
17093 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17094 return FALSE;
17095 }
17096
17097 /* No Type A response */
17098 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17099 return TRUE;
17100
17101 /* Wrong response is assigned, just ignore this response */
17102 if (!wlan_hdd_mdns_init_response(resptype_a,
17103 ini_config->mdns_resp_type_a, '.'))
17104 return TRUE;
17105
17106 /* Process response domain name */
17107 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17108 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17109 MDNS_TYPE_A);
17110 return FALSE;
17111 }
17112
17113 /* Process response Type, Class, TTL */
17114 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17115 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17116 MDNS_TYPE_A);
17117 return FALSE;
17118 }
17119
17120 /* Process response RDLength, RData */
17121 len = sizeof(uint16_t) + sizeof(uint32_t);
17122 len += resp_info->resp_len;
17123 if (len >= MAX_MDNS_RESP_LEN) {
17124 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17125 return FALSE;
17126 }
17127 value = sizeof(uint32_t);
17128 wlan_hdd_mdns_format_response_u16(value, resp_info);
17129 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17130 resp_info);
17131
17132 EXIT();
17133 return TRUE;
17134}
17135
17136/**
17137 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17138 * @ini_config: Pointer to the struct hdd_config_t
17139 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17140 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17141 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17142 *
17143 * Type Txt response include QName, response type, class, TTL and text content.
17144 * Also, it will find the matched QName from resptype_A and compress the data.
17145 *
17146 * Return: Return boolean. TRUE for success, FALSE for fail.
17147 */
17148static bool
17149wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17150 sir_mdns_resp_info resp_info,
17151 struct hdd_mdns_resp_info *resptype_txt,
17152 struct hdd_mdns_resp_info *resptype_a)
17153{
17154 uint8_t num_matched;
17155 uint8_t num;
17156 uint16_t idx;
17157 uint16_t value = 0;
17158 uint32_t len;
17159 uint32_t total_len;
17160 bool status;
17161 struct hdd_mdns_resp_info resptype_content;
17162
17163 ENTER();
17164
17165 if ((ini_config == NULL) || (resp_info == NULL) ||
17166 (resptype_txt == NULL)) {
17167 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17168 return FALSE;
17169 }
17170
17171 /* No Type Txt response */
17172 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17173 return TRUE;
17174
17175 /* Wrong response is assigned, just ignore this response */
17176 if (!wlan_hdd_mdns_init_response(resptype_txt,
17177 ini_config->mdns_resp_type_txt, '.'))
17178 return TRUE;
17179
17180 /*
17181 * For data compression
17182 * Check if any strings are matched with Type A response
17183 */
17184 if (resptype_a && (resptype_a->num_entries > 0)) {
17185 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17186 resptype_a);
17187 if (num_matched > 0) {
17188 if (!wlan_hdd_mdns_compress_data(resp_info,
17189 resptype_txt, resptype_a, num_matched)) {
17190 hddLog(LOGE, FL("Fail to compress mDNS "
17191 "response (%d)!"), MDNS_TYPE_TXT);
17192 return FALSE;
17193 }
17194 } else {
17195 /*
17196 * num_matched is zero. Error!
17197 * At least ".local" is needed.
17198 */
17199 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17200 "response (%d)!"), MDNS_TYPE_TXT);
17201 return FALSE;
17202 }
17203 } else {
17204 /* no TypeA response, so show the whole data */
17205 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17206 resp_info)) {
17207 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17208 MDNS_TYPE_TXT);
17209 return FALSE;
17210 }
17211 }
17212
17213 /* Process response Type, Class, TTL */
17214 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17215 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17216 MDNS_TYPE_TXT);
17217 return FALSE;
17218 }
17219
17220 /*
17221 * Process response RDLength, RData.
17222 * TypeTxt RData include len.
17223 */
17224 status = wlan_hdd_mdns_init_response(&resptype_content,
17225 ini_config->mdns_resp_type_txt_content,
17226 '/');
17227 if (status == FALSE) {
17228 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17229 return FALSE;
17230 }
17231
17232 for (num = 0; num < resptype_content.num_entries; num++) {
17233 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17234 value += strlen((char *)&resptype_content.data[idx]);
17235 }
17236
17237 /* content len is uint16_t */
17238 total_len = sizeof(uint16_t);
17239 total_len += resp_info->resp_len + value +
17240 resptype_content.num_entries;
17241
17242 if (total_len >= MAX_MDNS_RESP_LEN) {
17243 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17244 return FALSE;
17245 }
17246 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17247 resp_info);
17248
17249 for (num = 0; num < resptype_content.num_entries; num++) {
17250 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17251 len = strlen((char *)&resptype_content.data[idx]);
17252 resp_info->resp_data[resp_info->resp_len] = len;
17253 resp_info->resp_len++;
17254
17255 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17256 &resptype_content.data[idx], len);
17257
17258 resp_info->resp_len += len;
17259 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17260 num, len, &resptype_content.data[idx]);
17261 }
17262
17263 EXIT();
17264 return TRUE;
17265}
17266
17267/**
17268 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17269 * @ini_config: Pointer to the struct hdd_config_t
17270 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17271 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17272 * domain name
17273 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17274 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17275 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17276 *
17277 * The Type Ptr response include Type PTR domain name in its data field.
17278 * Also, it will find the matched QName from the existing resptype_ptr,
17279 * resptype_txt, resptype_a and then compress the data.
17280 *
17281 * Return: Return boolean. TRUE for success, FALSE for fail.
17282 */
17283static bool
17284wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17285 sir_mdns_resp_info resp_info,
17286 struct hdd_mdns_resp_info *resptype_ptr_dn,
17287 struct hdd_mdns_resp_info *resptype_ptr,
17288 struct hdd_mdns_resp_info *resptype_txt,
17289 struct hdd_mdns_resp_info *resptype_a)
17290{
17291 uint8_t num_matched, numlist, size;
17292 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17293 struct hdd_mdns_resp_info *resp;
17294
17295 if ((ini_config == NULL) || (resp_info == NULL) ||
17296 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17297 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17298 return FALSE;
17299 }
17300
17301 /* No Type Ptr domain name response */
17302 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17303 return TRUE;
17304
17305 /* Wrong response is assigned, just ignore this response */
17306 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17307 ini_config->mdns_resp_type_ptr_dname, '.'))
17308 return TRUE;
17309
17310 /*
17311 * For data compression
17312 * Check if any strings are matched with previous
17313 * response.
17314 */
17315 numlist = 0;
17316 size = (MAX_MDNS_RESP_TYPE-1);
17317 size *= sizeof(struct hdd_mdns_resp_matched);
17318 vos_mem_zero(matchedlist, size);
17319 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17320 resptype_ptr);
17321 if (num_matched > 0) {
17322 matchedlist[numlist].num_matched = num_matched;
17323 matchedlist[numlist].type = MDNS_TYPE_PTR;
17324 numlist++;
17325 }
17326 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17327 num_matched = wlan_hdd_mdns_find_entries_from_end(
17328 resptype_ptr_dn, resptype_txt);
17329 if (num_matched > 0) {
17330 matchedlist[numlist].num_matched = num_matched;
17331 matchedlist[numlist].type = MDNS_TYPE_TXT;
17332 numlist++;
17333 }
17334 }
17335 if (resptype_a && (resptype_a->num_entries > 0)) {
17336 num_matched = wlan_hdd_mdns_find_entries_from_end(
17337 resptype_ptr_dn,resptype_a);
17338 if (num_matched > 0) {
17339 matchedlist[numlist].num_matched = num_matched;
17340 matchedlist[numlist].type = MDNS_TYPE_A;
17341 numlist++;
17342 }
17343 }
17344 if (numlist > 0) {
17345 if (numlist > 1)
17346 wlan_hdd_mdns_find_max(matchedlist, numlist);
17347 resp = NULL;
17348 switch (matchedlist[numlist-1].type) {
17349 case MDNS_TYPE_A:
17350 resp = resptype_a;
17351 break;
17352 case MDNS_TYPE_TXT:
17353 resp = resptype_txt;
17354 break;
17355 case MDNS_TYPE_PTR:
17356 resp = resptype_ptr;
17357 break;
17358 default:
17359 hddLog(LOGE, FL("Fail to compress mDNS response "
17360 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17361 return FALSE;
17362 }
17363 num_matched = matchedlist[numlist-1].num_matched;
17364 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17365 resp, num_matched)) {
17366 hddLog(LOGE, FL("Fail to compress mDNS response "
17367 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17368 return FALSE;
17369 }
17370 } else {
17371 /* num = 0 -> no matched string */
17372 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17373 resp_info)) {
17374 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17375 MDNS_TYPE_PTR_DNAME);
17376 return FALSE;
17377 }
17378 }
17379
17380 return TRUE;
17381}
17382
17383/**
17384 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17385 * @ini_config: Pointer to the struct hdd_config_t
17386 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17387 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17388 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17389 * domain name
17390 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17391 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17392 *
17393 * The Type Ptr response include QName, response type, class, TTL and
17394 * Type PTR domain name. Also, it will find the matched QName from the
17395 * existing resptype_txt, resptype_a and then compress the data.
17396 *
17397 * Return: Return boolean. TRUE for success, FALSE for fail.
17398 */
17399static bool
17400wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17401 sir_mdns_resp_info resp_info,
17402 struct hdd_mdns_resp_info *resptype_ptr,
17403 struct hdd_mdns_resp_info *resptype_ptr_dn,
17404 struct hdd_mdns_resp_info *resptype_txt,
17405 struct hdd_mdns_resp_info *resptype_a)
17406{
17407 uint8_t num_matched, num_matched1;
17408 uint16_t value;
17409 uint8_t val_u8;
17410 uint32_t offset_data_len, len;
17411
17412 ENTER();
17413 if ((ini_config == NULL) || (resp_info == NULL) ||
17414 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17415 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17416 return FALSE;
17417 }
17418
17419 /* No Type Ptr response */
17420 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17421 return TRUE;
17422
17423 /* Wrong response is assigned, just ignore this response */
17424 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17425 ini_config->mdns_resp_type_ptr, '.'))
17426 return TRUE;
17427
17428 /*
17429 * For data compression
17430 * Check if any strings are matched with Type A response
17431 */
17432 num_matched = 0;
17433 num_matched1 = 0;
17434 if (resptype_a && (resptype_a->num_entries > 0)) {
17435 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17436 resptype_a);
17437 }
17438 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17439 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17440 resptype_ptr, resptype_txt);
17441 }
17442 if ((num_matched != num_matched1) ||
17443 ((num_matched > 0) && (num_matched1 > 0))) {
17444 if (num_matched >= num_matched1) {
17445 if (!wlan_hdd_mdns_compress_data(resp_info,
17446 resptype_ptr, resptype_a, num_matched)) {
17447 hddLog(LOGE, FL("Fail to compress mDNS "
17448 "response (%d)!"), MDNS_TYPE_PTR);
17449 return FALSE;
17450 }
17451 } else {
17452 /* num_matched is less than num_matched1 */
17453 if (!wlan_hdd_mdns_compress_data(resp_info,
17454 resptype_ptr, resptype_txt, num_matched1)) {
17455 hddLog(LOGE, FL("Fail to compress mDNS "
17456 "response (%d)!"), MDNS_TYPE_PTR);
17457 return FALSE;
17458 }
17459 }
17460 } else {
17461 /*
17462 * Both num_matched and num_matched1 are zero.
17463 * no TypeA & TypeTxt
17464 */
17465 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17466 resp_info)) {
17467 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17468 MDNS_TYPE_PTR);
17469 return FALSE;
17470 }
17471 }
17472
17473 /* Process response Type, Class, TTL */
17474 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17475 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17476 MDNS_TYPE_PTR);
17477 return FALSE;
17478 }
17479
17480 /*
17481 * Process response RDLength, RData (Ptr domain name)
17482 * Save the offset of RData length
17483 */
17484 offset_data_len = resp_info->resp_len;
17485 resp_info->resp_len += sizeof(uint16_t);
17486
17487 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17488 resptype_ptr_dn, resptype_ptr,
17489 resptype_txt, resptype_a)) {
17490 return FALSE;
17491 }
17492 /* Set the RData length */
17493 len = offset_data_len + sizeof(uint16_t);
17494 if ((resptype_ptr_dn->num_entries > 0) &&
17495 (resp_info->resp_len > len)) {
17496 value = resp_info->resp_len - len;
17497 val_u8 = (value & 0xff00) >> 8;
17498 resp_info->resp_data[offset_data_len] = val_u8;
17499 val_u8 = value & 0xff;
17500 resp_info->resp_data[offset_data_len+1] = val_u8;
17501 } else {
17502 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17503 MDNS_TYPE_PTR);
17504 return FALSE;
17505 }
17506
17507 EXIT();
17508 return TRUE;
17509}
17510
17511/**
17512 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17513 * @ini_config: Pointer to the struct hdd_config_t
17514 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17515 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17516 * target
17517 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17518 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17519 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17520 * domain name
17521 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17522 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17523 *
17524 * The Type service target is one of the data field in the Type SRV response.
17525 * Also, it will find the matched QName from the existing resptype_srv,
17526 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17527 * the data.
17528 *
17529 * Return: Return boolean. TRUE for success, FALSE for fail.
17530 */
17531static bool
17532wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17533 sir_mdns_resp_info resp_info,
17534 struct hdd_mdns_resp_info *resptype_srv_tgt,
17535 struct hdd_mdns_resp_info *resptype_srv,
17536 struct hdd_mdns_resp_info *resptype_ptr,
17537 struct hdd_mdns_resp_info *resptype_ptr_dn,
17538 struct hdd_mdns_resp_info *resptype_txt,
17539 struct hdd_mdns_resp_info *resptype_a)
17540{
17541 uint8_t num_matched, num, size;
17542 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17543 struct hdd_mdns_resp_info *resp;
17544
17545 if ((ini_config == NULL) || (resp_info == NULL) ||
17546 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17547 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17548 return FALSE;
17549 }
17550
17551 /* No Type Srv Target response */
17552 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17553 return TRUE;
17554
17555 /* Wrong response is assigned, just ignore this response */
17556 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17557 ini_config->mdns_resp_type_srv_target, '.'))
17558 return TRUE;
17559
17560 /*
17561 * For data compression
17562 * Check if any strings are matched with previous response.
17563 */
17564 num = 0;
17565 size = (MAX_MDNS_RESP_TYPE-1);
17566 size *= sizeof(struct hdd_mdns_resp_matched);
17567 vos_mem_zero(matchedlist, size);
17568 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17569 resptype_srv);
17570 if (num_matched > 0) {
17571 matchedlist[num].num_matched = num_matched;
17572 matchedlist[num].type = MDNS_TYPE_SRV;
17573 num++;
17574 }
17575 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17576 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17577 num_matched = wlan_hdd_mdns_find_entries_from_end(
17578 resptype_srv_tgt, resptype_ptr_dn);
17579 if (num_matched > 0) {
17580 matchedlist[num].num_matched = num_matched;
17581 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17582 num++;
17583 }
17584 }
17585 num_matched = wlan_hdd_mdns_find_entries_from_end(
17586 resptype_srv_tgt, resptype_ptr);
17587 if (num_matched > 0) {
17588 matchedlist[num].num_matched = num_matched;
17589 matchedlist[num].type = MDNS_TYPE_PTR;
17590 num++;
17591 }
17592 }
17593 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17594 num_matched = wlan_hdd_mdns_find_entries_from_end(
17595 resptype_srv_tgt, resptype_txt);
17596 if (num_matched > 0) {
17597 matchedlist[num].num_matched = num_matched;
17598 matchedlist[num].type = MDNS_TYPE_TXT;
17599 num++;
17600 }
17601 }
17602 if (resptype_a && (resptype_a->num_entries > 0)) {
17603 num_matched = wlan_hdd_mdns_find_entries_from_end(
17604 resptype_srv_tgt, resptype_a);
17605 if (num_matched > 0) {
17606 matchedlist[num].num_matched = num_matched;
17607 matchedlist[num].type = MDNS_TYPE_A;
17608 num++;
17609 }
17610 }
17611 if (num > 0) {
17612 if (num > 1)
17613 wlan_hdd_mdns_find_max(matchedlist, num);
17614 resp = NULL;
17615 switch (matchedlist[num-1].type) {
17616 case MDNS_TYPE_A:
17617 resp = resptype_a;
17618 break;
17619 case MDNS_TYPE_TXT:
17620 resp = resptype_txt;
17621 break;
17622 case MDNS_TYPE_PTR:
17623 resp = resptype_ptr;
17624 break;
17625 case MDNS_TYPE_PTR_DNAME:
17626 resp = resptype_ptr_dn;
17627 break;
17628 case MDNS_TYPE_SRV:
17629 resp = resptype_srv;
17630 break;
17631 default:
17632 hddLog(LOGE, FL("Fail to compress mDNS response "
17633 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17634 return FALSE;
17635 }
17636 num_matched = matchedlist[num-1].num_matched;
17637 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17638 resp, num_matched)) {
17639 hddLog(LOGE, FL("Fail to compress mDNS response "
17640 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17641 return FALSE;
17642 }
17643 } else {
17644 /* num = 0 -> no matched string */
17645 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17646 resp_info)) {
17647 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17648 MDNS_TYPE_SRV_TARGET);
17649 return FALSE;
17650 }
17651 }
17652
17653 return TRUE;
17654}
17655
17656/**
17657 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17658 * @ini_config: Pointer to the struct hdd_config_t
17659 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17660 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17661 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17662 * target
17663 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17664 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17665 * domain name
17666 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17667 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17668 *
17669 * The Type SRV (Service) response include QName, response type, class, TTL
17670 * and four kinds of data fields. Also, it will find the matched QName from
17671 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17672 * then compress the data.
17673 *
17674 * Return: Return boolean. TRUE for success, FALSE for fail.
17675 */
17676static bool
17677wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17678 sir_mdns_resp_info resp_info,
17679 struct hdd_mdns_resp_info *resptype_srv,
17680 struct hdd_mdns_resp_info *resptype_srv_tgt,
17681 struct hdd_mdns_resp_info *resptype_ptr,
17682 struct hdd_mdns_resp_info *resptype_ptr_dn,
17683 struct hdd_mdns_resp_info *resptype_txt,
17684 struct hdd_mdns_resp_info *resptype_a)
17685{
17686 uint8_t num_matched, num, size;
17687 uint16_t value;
17688 uint8_t val_u8;
17689 uint32_t offset_data_len, len;
17690 struct hdd_mdns_resp_info *resp;
17691 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17692
17693 ENTER();
17694
17695 if ((ini_config == NULL) || (resp_info == NULL) ||
17696 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17697 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17698 return FALSE;
17699 }
17700
17701 /* No Type Srv response */
17702 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17703 return TRUE;
17704
17705 /* Wrong response is assigned, just ignore this response */
17706 if (!wlan_hdd_mdns_init_response(resptype_srv,
17707 ini_config->mdns_resp_type_srv, '.'))
17708 return TRUE;
17709
17710 /*
17711 * For data compression
17712 * Check if any strings are matched with Type A response
17713 */
17714 num = 0;
17715 size = (MAX_MDNS_RESP_TYPE-1);
17716 size *= sizeof(struct hdd_mdns_resp_matched);
17717 vos_mem_zero(matchedlist, size);
17718 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17719 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17720 num_matched = wlan_hdd_mdns_find_entries_from_end(
17721 resptype_srv,
17722 resptype_ptr_dn);
17723 if (num_matched > 0) {
17724 matchedlist[num].num_matched = num_matched;
17725 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17726 num++;
17727 }
17728 }
17729 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17730 resptype_ptr);
17731 if (num_matched > 0) {
17732 matchedlist[num].num_matched = num_matched;
17733 matchedlist[num].type = MDNS_TYPE_PTR;
17734 num++;
17735 }
17736 }
17737 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17738 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17739 resptype_txt);
17740 if (num_matched > 0) {
17741 matchedlist[num].num_matched =num_matched;
17742 matchedlist[num].type = MDNS_TYPE_TXT;
17743 num++;
17744 }
17745 }
17746 if (resptype_a && (resptype_a->num_entries > 0)) {
17747 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17748 resptype_a);
17749 if (num_matched > 0) {
17750 matchedlist[num].num_matched = num_matched;
17751 matchedlist[num].type = MDNS_TYPE_A;
17752 num++;
17753 }
17754 }
17755 if (num > 0) {
17756 if (num > 1)
17757 wlan_hdd_mdns_find_max(matchedlist, num);
17758 resp = NULL;
17759 switch (matchedlist[num-1].type) {
17760 case MDNS_TYPE_A:
17761 resp = resptype_a;
17762 break;
17763 case MDNS_TYPE_TXT:
17764 resp = resptype_txt;
17765 break;
17766 case MDNS_TYPE_PTR:
17767 resp = resptype_ptr;
17768 break;
17769 case MDNS_TYPE_PTR_DNAME:
17770 resp = resptype_ptr_dn;
17771 break;
17772 default:
17773 hddLog(LOGE, FL("Fail to compress mDNS response "
17774 "(%d)!"), MDNS_TYPE_SRV);
17775 return FALSE;
17776 }
17777 num_matched = matchedlist[num-1].num_matched;
17778 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17779 resp, num_matched)) {
17780 hddLog(LOGE, FL("Fail to compress mDNS response "
17781 "(%d)!"), MDNS_TYPE_SRV);
17782 return FALSE;
17783 }
17784 } else {
17785 /* num = 0 -> no matched string */
17786 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17787 resp_info)) {
17788 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17789 MDNS_TYPE_SRV);
17790 return FALSE;
17791 }
17792 }
17793
17794 /* Process response Type, Class, TTL */
17795 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17796 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17797 MDNS_TYPE_SRV);
17798 return FALSE;
17799 }
17800
17801 /*
17802 * Process response RDLength, RData (Srv target name)
17803 * Save the offset of RData length
17804 */
17805 offset_data_len = resp_info->resp_len;
17806 resp_info->resp_len += sizeof(uint16_t);
17807
17808 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17809 if (len >= MAX_MDNS_RESP_LEN) {
17810 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17811 return FALSE;
17812 }
17813
17814 /* set Srv Priority */
17815 value = ini_config->mdns_resp_type_srv_priority;
17816 wlan_hdd_mdns_format_response_u16(value, resp_info);
17817 /* set Srv Weight */
17818 value = ini_config->mdns_resp_type_srv_weight;
17819 wlan_hdd_mdns_format_response_u16(value, resp_info);
17820 /* set Srv Port */
17821 value = ini_config->mdns_resp_type_srv_port;
17822 wlan_hdd_mdns_format_response_u16(value, resp_info);
17823
17824 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17825 resptype_srv_tgt, resptype_srv,
17826 resptype_ptr, resptype_ptr_dn,
17827 resptype_txt, resptype_a)) {
17828 return FALSE;
17829 }
17830 /* Set the RData length */
17831 len = offset_data_len + sizeof(uint16_t);
17832 if ((resptype_srv_tgt->num_entries > 0) &&
17833 (resp_info->resp_len > len)) {
17834 value = resp_info->resp_len - len;
17835 val_u8 = (value & 0xff00) >> 8;
17836 resp_info->resp_data[offset_data_len] = val_u8;
17837 val_u8 = value & 0xff;
17838 resp_info->resp_data[offset_data_len+1] = val_u8;
17839 } else {
17840 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17841 MDNS_TYPE_SRV);
17842 return FALSE;
17843 }
17844
17845 EXIT();
17846 return TRUE;
17847}
17848
17849/**
17850 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17851 * @response: Pointer to the struct hdd_mdns_resp_info
17852 *
17853 * Return: None
17854 */
17855static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17856{
17857 if (response && response->data)
17858 vos_mem_free(response->data);
17859 if (response && response->offset)
17860 vos_mem_free(response->offset);
17861}
17862
17863/**
17864 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17865 * @ini_config: Pointer to the struct hdd_config_t
17866 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17867 *
17868 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17869 * and Type Service). Each response contains QName, response type, class, TTL
17870 * and data fields.
17871 *
17872 * Return: Return boolean. TRUE for success, FALSE for fail.
17873 */
17874static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17875 sir_mdns_resp_info resp_info)
17876{
17877 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17878 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17879 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17880 uint32_t num_res_records = 0;
17881 bool status = FALSE;
17882
17883 ENTER();
17884
17885 wlan_hdd_mdns_reset_response(&resptype_a);
17886 wlan_hdd_mdns_reset_response(&resptype_txt);
17887 wlan_hdd_mdns_reset_response(&resptype_ptr);
17888 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17889 wlan_hdd_mdns_reset_response(&resptype_srv);
17890 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17891
17892 resp_info->resp_len = 0;
17893
17894 /* Process Type A response */
17895 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17896 &resptype_a))
17897 goto err_resptype_a;
17898
17899 if ((resptype_a.num_entries > 0) &&
17900 (strlen((char *)&resptype_a.data[0]) > 0))
17901 num_res_records++;
17902
17903 /* Process Type TXT response */
17904 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17905 &resptype_txt, &resptype_a))
17906 goto err_resptype_txt;
17907
17908 if ((resptype_txt.num_entries > 0) &&
17909 (strlen((char *)&resptype_txt.data[0]) > 0))
17910 num_res_records++;
17911
17912 /* Process Type PTR response */
17913 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17914 &resptype_ptr, &resptype_ptr_dn,
17915 &resptype_txt, &resptype_a))
17916 goto err_resptype_ptr;
17917
17918 if ((resptype_ptr.num_entries > 0) &&
17919 (strlen((char *)&resptype_ptr.data[0]) > 0))
17920 num_res_records++;
17921
17922 /* Process Type SRV response */
17923 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17924 &resptype_srv, &resptype_srv_tgt,
17925 &resptype_ptr, &resptype_ptr_dn,
17926 &resptype_txt, &resptype_a))
17927 goto err_resptype_srv;
17928
17929 if ((resptype_srv.num_entries > 0) &&
17930 (strlen((char *)&resptype_srv.data[0]) > 0))
17931 num_res_records++;
17932
17933 resp_info->resourceRecord_count = num_res_records;
17934 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17935 "%s: Pack mDNS response data successfully!", __func__);
17936 status = TRUE;
17937
17938err_resptype_srv:
17939 wlan_hdd_mdns_free_mem(&resptype_srv);
17940 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17941
17942err_resptype_ptr:
17943 wlan_hdd_mdns_free_mem(&resptype_ptr);
17944 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17945
17946err_resptype_txt:
17947 wlan_hdd_mdns_free_mem(&resptype_txt);
17948
17949err_resptype_a:
17950 wlan_hdd_mdns_free_mem(&resptype_a);
17951
17952 EXIT();
17953 return status;
17954}
17955
17956/**
17957 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17958 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17959 *
17960 * This function will set FQDN/unique FQDN (full qualified domain name)
17961 * and the mDNS response. Then send them to SME.
17962 *
17963 * Return: Return boolean. TRUE for success, FALSE for fail.
17964 */
17965bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17966{
17967 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17968 sir_mdns_offload_info mdns_offload_info;
17969 sir_mdns_fqdn_info mdns_fqdn_info;
17970 sir_mdns_resp_info mdns_resp_info;
17971 uint32_t fqdn_len, ufqdn_len;
17972
17973 ENTER();
17974
17975 /* 1. Prepare the MDNS fqdn request to send to SME */
17976 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17977 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17978 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17979 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17980 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17981 return FALSE;
17982 }
17983
17984 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17985 if (NULL == mdns_fqdn_info) {
17986 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17987 return FALSE;
17988 }
17989 /* MDNS fqdn request */
17990 if (fqdn_len > 0) {
17991 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17992 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17993 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17994 mdns_fqdn_info->fqdn_len = fqdn_len;
17995 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17996 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17997 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17998 hdd_ctx->cfg_ini->mdns_fqdn,
17999 mdns_fqdn_info->fqdn_len);
18000
18001 if (eHAL_STATUS_SUCCESS !=
18002 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18003 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18004 vos_mem_free(mdns_fqdn_info);
18005 return FALSE;
18006 }
18007 }
18008 /* MDNS unique fqdn request */
18009 if (ufqdn_len > 0) {
18010 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18011 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18012 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
18013 mdns_fqdn_info->fqdn_len = ufqdn_len;
18014 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18015 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18016 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18017 hdd_ctx->cfg_ini->mdns_uniquefqdn,
18018 mdns_fqdn_info->fqdn_len);
18019 if (eHAL_STATUS_SUCCESS !=
18020 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18021 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18022 vos_mem_free(mdns_fqdn_info);
18023 return FALSE;
18024 }
18025 }
18026 vos_mem_free(mdns_fqdn_info);
18027
18028 /* 2. Prepare the MDNS response request to send to SME */
18029 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18030 if (NULL == mdns_resp_info) {
18031 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18032 return FALSE;
18033 }
18034
18035 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18036 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18037 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18038 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18039 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18040 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18041 vos_mem_free(mdns_resp_info);
18042 return FALSE;
18043 }
18044 if (eHAL_STATUS_SUCCESS !=
18045 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18046 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18047 vos_mem_free(mdns_resp_info);
18048 return FALSE;
18049 }
18050 vos_mem_free(mdns_resp_info);
18051
18052 /* 3. Prepare the MDNS Enable request to send to SME */
18053 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18054 if (NULL == mdns_offload_info) {
18055 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18056 return FALSE;
18057 }
18058
18059 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18060
18061 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18062 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18063 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18064 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18065 if (eHAL_STATUS_SUCCESS !=
18066 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18067 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18068 vos_mem_free(mdns_offload_info);
18069 return FALSE;
18070 }
18071
18072 vos_mem_free(mdns_offload_info);
18073 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18074 "%s: enable mDNS offload successfully!", __func__);
18075 return TRUE;
18076}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018077
18078
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018079#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018080
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018081/**
18082 * wlan_hdd_start_sap() - This function starts bss of SAP.
18083 * @ap_adapter: SAP adapter
18084 *
18085 * This function will process the starting of sap adapter.
18086 *
18087 * Return: void.
18088 */
18089void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18090{
18091 hdd_ap_ctx_t *hdd_ap_ctx;
18092 hdd_hostapd_state_t *hostapd_state;
18093 VOS_STATUS vos_status;
18094 hdd_context_t *hdd_ctx;
18095 tsap_Config_t *pConfig;
18096
18097 if (NULL == ap_adapter) {
18098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18099 FL("ap_adapter is NULL here"));
18100 return;
18101 }
18102
18103 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18104 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18105 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18106 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18107
18108 mutex_lock(&hdd_ctx->sap_lock);
18109 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18110 goto end;
18111
18112 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18113 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18114 goto end;
18115 }
18116
18117 vos_event_reset(&hostapd_state->vosEvent);
18118 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18119 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18120 != VOS_STATUS_SUCCESS) {
18121 goto end;
18122 }
18123
18124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18125 FL("Waiting for SAP to start"));
18126 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18127 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18129 FL("SAP Start failed"));
18130 goto end;
18131 }
18132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18133 FL("SAP Start Success"));
18134 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18135
18136 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18137 hostapd_state->bCommit = TRUE;
18138
18139end:
18140 mutex_unlock(&hdd_ctx->sap_lock);
18141 return;
18142}
18143
Manjeet Singh3ed79242017-01-11 19:04:32 +053018144#ifdef WLAN_FEATURE_TSF
18145
18146/**
18147 * hdd_tsf_cb() - handle tsf request callback
18148 *
18149 * @pcb_cxt: pointer to the hdd_contex
18150 * @ptsf: pointer to struct stsf
18151 *
18152 * Based on the request sent .
18153 *
18154 * Return: Describe the execute result of this routine
18155 */
18156static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18157{
18158 hdd_context_t *hddctx;
18159 int status;
18160 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18161
18162 if (pcb_ctx == NULL || ptsf == NULL) {
18163 hddLog(VOS_TRACE_LEVEL_ERROR,
18164 FL("HDD context is not valid"));
18165 return -EINVAL;
18166 }
18167
18168 hddctx = (hdd_context_t *)pcb_ctx;
18169 status = wlan_hdd_validate_context(hddctx);
18170 if (0 != status)
18171 return -EINVAL;
18172
18173 if (NULL == adapter) {
18174 hddLog(VOS_TRACE_LEVEL_ERROR,
18175 FL("failed to find adapter"));
18176 return -EINVAL;
18177 }
18178
18179 hddLog(VOS_TRACE_LEVEL_INFO,
18180 FL("tsf cb handle event, device_mode is %d"),
18181 adapter->device_mode);
18182
18183 /* copy the return value to hdd_tsf_ctx in adapter*/
18184 if (ptsf->tsf_req_status) {
18185
18186 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18187 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18188 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18189 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18190 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18191
18192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18193 ptsf->tsf_req_status);
18194 return ptsf->tsf_req_status;
18195 }
18196 /* If this is a get request.Store the tsf values in adapter. */
18197 if (!ptsf->set_tsf_req) {
18198 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18199 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18200 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18201 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18202 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18203 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18204
18205 hddLog(VOS_TRACE_LEVEL_INFO,
18206 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18207 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18208 }
18209 else {
18210 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18211 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18212 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18213 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18214 }
18215 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18216 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18217 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18218
18219 /* free allocated mem */
18220 vos_mem_free(ptsf);
18221
18222 return 0;
18223}
18224
18225/**
18226 * hdd_capture_tsf() - capture tsf
18227 *
18228 * @adapter: pointer to adapter
18229 * @buf: pointer to upper layer buf
18230 * @len : the length of buf
18231 *
18232 * This function returns tsf value to uplayer.
18233 *
18234 * Return: Describe the execute result of this routine
18235 */
18236int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18237{
18238 int ret = 0;
18239 hdd_station_ctx_t *hdd_sta_ctx;
18240 hdd_context_t *hdd_ctx;
18241 tSirCapTsfParams cap_tsf_params;
18242 VOS_STATUS status;
18243
18244 if (adapter == NULL || buf == NULL) {
18245 hddLog(VOS_TRACE_LEVEL_ERROR,
18246 FL("invalid pointer"));
18247 return -EINVAL;
18248 }
18249 if (len != 1)
18250 return -EINVAL;
18251
18252 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18253
18254 if (wlan_hdd_validate_context(hdd_ctx)) {
18255 hddLog(VOS_TRACE_LEVEL_ERROR,
18256 FL("invalid hdd ctx"));
18257 return -EINVAL;
18258 }
18259 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18260 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18261 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18262 if (hdd_sta_ctx->conn_info.connState !=
18263 eConnectionState_Associated) {
18264
18265 hddLog(VOS_TRACE_LEVEL_INFO,
18266 FL("failed to cap tsf, not connect with ap"));
18267 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18268 return ret;
18269 }
18270 }
18271 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18272 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18273 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18274 hddLog(VOS_TRACE_LEVEL_INFO,
18275 FL("Soft AP / P2p GO not beaconing"));
18276 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18277 return ret;
18278 }
18279 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18280 hddLog(VOS_TRACE_LEVEL_INFO,
18281 FL("current in capture state, pls reset"));
18282 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18283 } else {
18284 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18285 buf[0] = TSF_RETURN;
18286 cap_tsf_params.session_id = adapter->sessionId;
18287 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18288 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18289
18290 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18291 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18292 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18293 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18294
18295 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18296
18297 if (ret != VOS_STATUS_SUCCESS) {
18298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18299 buf[0] = TSF_CAPTURE_FAIL;
18300 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18301 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18302 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18303 return -EINVAL;
18304 }
18305 /* wait till we get a response from fw */
18306 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18307 tsf_capture_done_event,
18308 HDD_TSF_CAP_REQ_TIMEOUT);
18309
18310 if (!VOS_IS_STATUS_SUCCESS(status)) {
18311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18312 ("capture tsf vos wait for single_event failed!! %d"),
18313 adapter->tsf_cap_ctx.tsf_get_state);
18314
18315 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18316 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18317 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18318
18319 return -EINVAL;
18320 }
18321 }
18322 buf[0] = TSF_RETURN;
18323 hddLog(VOS_TRACE_LEVEL_INFO,
18324 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18325 return ret;
18326}
18327
18328/**
18329 * hdd_indicate_tsf() - return tsf to uplayer
18330 *
18331 * @adapter: pointer to adapter
18332 * @buf: pointer to uplayer buf
18333 * @len : the length of buf
18334 *
18335 * This function returns tsf value to uplayer.
18336 *
18337 * Return: Describe the execute result of this routine
18338 */
18339int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18340{
18341 int ret = 0;
18342 hdd_station_ctx_t *hdd_sta_ctx;
18343 hdd_context_t *hdd_ctx;
18344 tSirCapTsfParams cap_tsf_params;
18345 VOS_STATUS status;
18346
18347 if (adapter == NULL || buf == NULL) {
18348 hddLog(VOS_TRACE_LEVEL_ERROR,
18349 FL("invalid pointer"));
18350 return -EINVAL;
18351 }
18352 if (len != 3)
18353 return -EINVAL;
18354
18355 buf [1] = 0;
18356 buf [2] = 0;
18357 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18358
18359 if (wlan_hdd_validate_context(hdd_ctx)) {
18360 hddLog(VOS_TRACE_LEVEL_ERROR,
18361 FL("invalid hdd ctx"));
18362 return -EINVAL;
18363 }
18364 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18365 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18366 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18367 if (hdd_sta_ctx->conn_info.connState !=
18368 eConnectionState_Associated) {
18369
18370 hddLog(VOS_TRACE_LEVEL_INFO,
18371 FL("failed to cap tsf, not connect with ap"));
18372 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18373 return ret;
18374 }
18375 }
18376 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18377 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18378 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18379 hddLog(VOS_TRACE_LEVEL_INFO,
18380 FL("Soft AP / P2p GO not beaconing"));
18381 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18382 return ret;
18383 }
18384
18385 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18386 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18387 hddLog(VOS_TRACE_LEVEL_INFO,
18388 FL("Not in capture state,Enter capture state first"));
18389 buf[0] = TSF_GET_FAIL;
18390 } else {
18391 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18392 cap_tsf_params.session_id = adapter->sessionId;
18393 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18394 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18395
18396 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18397
18398 if (ret != VOS_STATUS_SUCCESS) {
18399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18400 buf[0] = TSF_CAPTURE_FAIL;
18401 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18402 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18403 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18404 return -EINVAL;
18405 }
18406 /* wait till we get a response from fw */
18407 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18408 tsf_capture_done_event,
18409 HDD_TSF_GET_REQ_TIMEOUT);
18410
18411 if (!VOS_IS_STATUS_SUCCESS(status)) {
18412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18413 ("capture tsf vos wait for single_event failed!! %d"),
18414 status);
18415
18416 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18417 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18418 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18419 return status;
18420 }
18421 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18422 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18423
18424 hddLog(VOS_TRACE_LEVEL_INFO,
18425 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18426 buf[0], buf[1], buf[2]);
18427 }
18428 hddLog(VOS_TRACE_LEVEL_INFO,
18429 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18430 return ret;
18431}
18432
18433void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18434{
18435
18436 if (adapter == NULL) {
18437 hddLog(VOS_TRACE_LEVEL_ERROR,
18438 FL("TSF init on a null adapter!"));
18439 return;
18440 }
18441
18442 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18443 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18444 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18445 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18446 adapter->tsf_cap_ctx.tsf_high = 0;
18447 adapter->tsf_cap_ctx.tsf_low = 0;
18448}
18449
18450#endif
18451
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018452bool hdd_is_memdump_supported(void)
18453{
18454#ifdef WLAN_FEATURE_MEMDUMP
18455 return true;
18456#endif
18457 return false;
18458}
18459
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018460bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18461{
18462 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18463 hdd_adapter_t *adapter;
18464 VOS_STATUS status;
18465
18466 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18467 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18468 adapter = adapter_node->pAdapter;
18469 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18470 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18471 test_bit(DEVICE_IFACE_OPENED,
18472 &adapter->event_flags)){
18473 return true;
18474 }
18475 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18476 adapter_node = next;
18477 }
18478
18479 return false;
18480}
18481
Jeff Johnson295189b2012-06-20 16:38:30 -070018482//Register the module init/exit functions
18483module_init(hdd_module_init);
18484module_exit(hdd_module_exit);
18485
18486MODULE_LICENSE("Dual BSD/GPL");
18487MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18488MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18489
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018490static const struct kernel_param_ops con_mode_ops = {
18491 .set = con_mode_handler,
18492 .get = param_get_int,
18493};
18494
18495static const struct kernel_param_ops fwpath_ops = {
18496 .set = fwpath_changed_handler,
18497 .get = param_get_string,
18498};
18499
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018500#ifdef MODULE
18501module_param(con_mode, int, 0);
18502#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018503module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018504 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018505#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018506
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018507module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018508 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018509
18510module_param(enable_dfs_chan_scan, int,
18511 S_IRUSR | S_IRGRP | S_IROTH);
18512
18513module_param(enable_11d, int,
18514 S_IRUSR | S_IRGRP | S_IROTH);
18515
18516module_param(country_code, charp,
18517 S_IRUSR | S_IRGRP | S_IROTH);