blob: 0021b51486ba2a7d13bc74878b5e359d191ffba1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Abhishek Singh00b71972016-01-07 10:51:04 +0530179#ifdef WLAN_FEATURE_RMC
180/*
181 * Ibss prop IE from command will be of size:
182 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
183 * OUI_DATA should be at least 3 bytes long
184 */
185#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
186#endif
187
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800188#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189#define TID_MIN_VALUE 0
190#define TID_MAX_VALUE 15
191static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
192 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800193static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
194 tCsrEseBeaconReq *pEseBcnReq);
195#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700196
Atul Mittal1d722422014-03-19 11:15:07 +0530197/*
198 * Maximum buffer size used for returning the data back to user space
199 */
200#define WLAN_MAX_BUF_SIZE 1024
201#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700202
Abhishek Singh00b71972016-01-07 10:51:04 +0530203/*
204 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
205 * we will split the printing.
206 */
207#define NUM_OF_STA_DATA_TO_PRINT 16
208
209#ifdef WLAN_FEATURE_RMC
210#define WLAN_NLINK_CESIUM 30
211#endif
212
c_hpothu92367912014-05-01 15:18:17 +0530213//wait time for beacon miss rate.
214#define BCN_MISS_RATE_TIME 500
215
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530216/*
217 * Android DRIVER command structures
218 */
219struct android_wifi_reassoc_params {
220 unsigned char bssid[18];
221 int channel;
222};
223
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530224static vos_wake_lock_t wlan_wake_lock;
225
Jeff Johnson295189b2012-06-20 16:38:30 -0700226/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700227static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700230static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
231static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530233
234#ifdef WLAN_FEATURE_RMC
235static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
236
237static int hdd_open_cesium_nl_sock(void);
238static void hdd_close_cesium_nl_sock(void);
239static struct sock *cesium_nl_srv_sock;
240static v_U16_t cesium_pid;
241
242static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
243 tANI_U8 *tx_fail_count,
244 tANI_U16 *pid);
245
246static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
247
248#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700249void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800250void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700251
Jeff Johnson295189b2012-06-20 16:38:30 -0700252v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530253 struct sk_buff *skb
254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
255 , void *accel_priv
256#endif
257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
258 , select_queue_fallback_t fallback
259#endif
260);
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
262#ifdef WLAN_FEATURE_PACKET_FILTERING
263static void hdd_set_multicast_list(struct net_device *dev);
264#endif
265
266void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
267
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800268#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
270static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700271static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
272 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
273 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530274static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
275 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800276#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530277
278/* Store WLAN driver info in a global variable such that crash debugger
279 can extract it from driver debug symbol and crashdump for post processing */
280tANI_U8 g_wlan_driver[ ] = "pronto_driver";
281
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800282#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700283VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285
Mihir Shetee1093ba2014-01-21 20:13:32 +0530286static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530287const char * hdd_device_modetoString(v_U8_t device_mode)
288{
289 switch(device_mode)
290 {
291 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
292 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
293 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
295 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
296 CASE_RETURN_STRING( WLAN_HDD_FTM );
297 CASE_RETURN_STRING( WLAN_HDD_IBSS );
298 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
299 default:
300 return "device_mode Unknown";
301 }
302}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530303
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530304static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 unsigned long state,
306 void *ndev)
307{
308 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700311#ifdef WLAN_BTAMP_FEATURE
312 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530314 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315
316 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700318 (strncmp(dev->name, "p2p", 3)))
319 return NOTIFY_DONE;
320
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700322 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 VOS_ASSERT(0);
328 return NOTIFY_DONE;
329 }
330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
332 if (NULL == pHddCtx)
333 {
334 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
335 VOS_ASSERT(0);
336 return NOTIFY_DONE;
337 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800338 if (pHddCtx->isLogpInProgress)
339 return NOTIFY_DONE;
340
Jeff Johnson27cee452013-03-27 11:10:24 -0700341
342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
343 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344
345 switch (state) {
346 case NETDEV_REGISTER:
347 break;
348
349 case NETDEV_UNREGISTER:
350 break;
351
352 case NETDEV_UP:
353 break;
354
355 case NETDEV_DOWN:
356 break;
357
358 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 if(TRUE == pAdapter->isLinkUpSvcNeeded)
360 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 break;
362
363 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530364 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530365 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 {
367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
368 "%s: Timeout occurred while waiting for abortscan %ld",
369 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 }
371 else
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530374 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 }
376#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 status = WLANBAP_StopAmp();
379 if(VOS_STATUS_SUCCESS != status )
380 {
381 pHddCtx->isAmpAllowed = VOS_TRUE;
382 hddLog(VOS_TRACE_LEVEL_FATAL,
383 "%s: Failed to stop AMP", __func__);
384 }
385 else
386 {
387 //a state m/c implementation in PAL is TBD to avoid this delay
388 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700389 if ( pHddCtx->isAmpAllowed )
390 {
391 WLANBAP_DeregisterFromHCI();
392 pHddCtx->isAmpAllowed = VOS_FALSE;
393 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700394 }
395#endif //WLAN_BTAMP_FEATURE
396 break;
397
398 default:
399 break;
400 }
401
402 return NOTIFY_DONE;
403}
404
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530405static int hdd_netdev_notifier_call(struct notifier_block * nb,
406 unsigned long state,
407 void *ndev)
408{
409 int ret;
410 vos_ssr_protect(__func__);
411 ret = __hdd_netdev_notifier_call( nb, state, ndev);
412 vos_ssr_unprotect(__func__);
413 return ret;
414}
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416struct notifier_block hdd_netdev_notifier = {
417 .notifier_call = hdd_netdev_notifier_call,
418};
419
420/*---------------------------------------------------------------------------
421 * Function definitions
422 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700423void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
424void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700425//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700426static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700427#ifndef MODULE
428/* current con_mode - used only for statically linked driver
429 * con_mode is changed by userspace to indicate a mode change which will
430 * result in calling the module exit and init functions. The module
431 * exit function will clean up based on the value of con_mode prior to it
432 * being changed by userspace. So curr_con_mode records the current con_mode
433 * for exit when con_mode becomes the next mode for init
434 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700435static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700436#endif
437
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530438#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
439/**
440 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
441 * @hdd_ctx: hdd global context
442 *
443 * Return: none
444 */
445static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
446{
447 uint8_t i;
448
449 mutex_init(&hdd_ctx->op_ctx.op_lock);
450 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
451 {
452 hdd_ctx->op_ctx.op_table[i].request_id = 0;
453 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
454 }
455}
456#else
457static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
458{
459}
460#endif
461
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800462/**---------------------------------------------------------------------------
463
464 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = VOS_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 vos_trace_setValue(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
502
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504/**---------------------------------------------------------------------------
505
506 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
507
508 Called immediately after the cfg.ini is read in order to configure
509 the desired trace levels in the WDI.
510
511 \param - moduleId - module whose trace level is being configured
512 \param - bitmask - bitmask of log levels to be enabled
513
514 \return - void
515
516 --------------------------------------------------------------------------*/
517static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
518{
519 wpt_tracelevel level;
520
521 /* if the bitmask is the default value, then a bitmask was not
522 specified in cfg.ini, so leave the logging level alone (it
523 will remain at the "compiled in" default value) */
524 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
525 {
526 return;
527 }
528
529 /* a mask was specified. start by disabling all logging */
530 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
531
532 /* now cycle through the bitmask until all "set" bits are serviced */
533 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
534 while (0 != bitmask)
535 {
536 if (bitmask & 1)
537 {
538 wpalTraceSetLevel(moduleId, level, 1);
539 }
540 level++;
541 bitmask >>= 1;
542 }
543}
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530545/*
546 * FUNCTION: wlan_hdd_validate_context
547 * This function is used to check the HDD context
548 */
549int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
550{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530551
552 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530555 "%s: HDD context is Null", __func__);
556 return -ENODEV;
557 }
558
559 if (pHddCtx->isLogpInProgress)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530562 "%s: LOGP %s. Ignore!!", __func__,
563 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
564 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530565 return -EAGAIN;
566 }
567
Mihir Shete18156292014-03-11 15:38:30 +0530568 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530569 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
572 return -EAGAIN;
573 }
574 return 0;
575}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576#ifdef CONFIG_ENABLE_LINUX_REG
577void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
578{
579 hdd_adapter_t *pAdapter = NULL;
580 hdd_station_ctx_t *pHddStaCtx = NULL;
581 eCsrPhyMode phyMode;
582 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530583
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700584 if (NULL == pHddCtx)
585 {
586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
587 "HDD Context is null !!");
588 return ;
589 }
590
591 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
592 if (NULL == pAdapter)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "pAdapter is null !!");
596 return ;
597 }
598
599 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
600 if (NULL == pHddStaCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "pHddStaCtx is null !!");
604 return ;
605 }
606
607 cfg_param = pHddCtx->cfg_ini;
608 if (NULL == cfg_param)
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
611 "cfg_params not available !!");
612 return ;
613 }
614
615 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
616
617 if (!pHddCtx->isVHT80Allowed)
618 {
619 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
620 (eCSR_DOT11_MODE_11ac == phyMode) ||
621 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
624 "Setting phymode to 11n!!");
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
626 }
627 }
628 else
629 {
630 /*New country Supports 11ac as well resetting value back from .ini*/
631 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
632 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
633 return ;
634 }
635
636 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
637 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
638 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
639 {
640 VOS_STATUS vosStatus;
641
642 // need to issue a disconnect to CSR.
643 INIT_COMPLETION(pAdapter->disconnect_comp_var);
644 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
645 pAdapter->sessionId,
646 eCSR_DISCONNECT_REASON_UNSPECIFIED );
647
648 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530649 {
650 long ret;
651
652 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530654 if (0 >= ret)
655 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
656 ret);
657 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700658
659 }
660}
661#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
663{
664 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
666 hdd_config_t *cfg_param;
667 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530668 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669
670 if (NULL == pHddCtx)
671 {
672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
673 "HDD Context is null !!");
674 return ;
675 }
676
677 cfg_param = pHddCtx->cfg_ini;
678
679 if (NULL == cfg_param)
680 {
681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
682 "cfg_params not available !!");
683 return ;
684 }
685
686 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
687
688 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
689 {
690 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
691 (eCSR_DOT11_MODE_11ac == phyMode) ||
692 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
693 {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 "Setting phymode to 11n!!");
696 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
697 }
698 }
699 else
700 {
701 /*New country Supports 11ac as well resetting value back from .ini*/
702 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
703 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
704 return ;
705 }
706
707 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
708 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
709 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
710 {
711 VOS_STATUS vosStatus;
712
713 // need to issue a disconnect to CSR.
714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
715 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
716 pAdapter->sessionId,
717 eCSR_DISCONNECT_REASON_UNSPECIFIED );
718
719 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530720 {
721 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530723 if (ret <= 0)
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "wait on disconnect_comp_var is failed %ld", ret);
727 }
728 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729
730 }
731}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700732#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530733
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700734void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
735{
736 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
737 hdd_config_t *cfg_param;
738
739 if (NULL == pHddCtx)
740 {
741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
742 "HDD Context is null !!");
743 return ;
744 }
745
746 cfg_param = pHddCtx->cfg_ini;
747
748 if (NULL == cfg_param)
749 {
750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
751 "cfg_params not available !!");
752 return ;
753 }
754
Agarwal Ashish738843c2014-09-25 12:27:56 +0530755 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
756 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700757 {
758 /*New country doesn't support DFS */
759 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
760 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700761
762}
763
Abhishek Singh00b71972016-01-07 10:51:04 +0530764#ifdef WLAN_FEATURE_RMC
765static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
766{
767 tANI_U8 *inPtr = pValue;
768 int tempInt;
769 int v = 0;
770 char buf[32];
771 *pRmcEnable = 0;
772
773 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
774 /*no argument after the command*/
775 if (NULL == inPtr)
776 {
777 return 0;
778 }
779
780 /*no space after the command*/
781 else if (SPACE_ASCII_VALUE != *inPtr)
782 {
783 return 0;
784 }
785
786 /*removing empty spaces*/
787 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
788
789 /*no argument followed by spaces*/
790 if ('\0' == *inPtr)
791 {
792 return 0;
793 }
794
795 /* getting the first argument which enables or disables RMC
796 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530797 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530798 v = kstrtos32(buf, 10, &tempInt);
799 if ( v < 0)
800 {
801 return -EINVAL;
802 }
803
804 *pRmcEnable = tempInt;
805
806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
807 "ucRmcEnable: %d", *pRmcEnable);
808
809 return 0;
810}
811
812/* Function header left blank Intentionally */
813static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
814 tANI_U32 *pActionPeriod)
815{
816 tANI_U8 *inPtr = pValue;
817 int tempInt;
818 int v = 0;
819 char buf[32];
820 *pActionPeriod = 0;
821
822 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
823 /*no argument after the command*/
824 if (NULL == inPtr)
825 {
826 return -EINVAL;
827 }
828
829 /*no space after the command*/
830 else if (SPACE_ASCII_VALUE != *inPtr)
831 {
832 return -EINVAL;
833 }
834
835 /*removing empty spaces*/
836 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
837
838 /*no argument followed by spaces*/
839 if ('\0' == *inPtr)
840 {
841 return 0;
842 }
843
844 /* getting the first argument which enables or disables RMC
845 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530846 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530847 v = kstrtos32(buf, 10, &tempInt);
848 if ( v < 0)
849 {
850 return -EINVAL;
851 }
852
853 /* Range checking for passed paramter */
854 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
855 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
856 {
857 return -EINVAL;
858 }
859
860 *pActionPeriod = tempInt;
861
862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
863 "uActionPeriod: %d", *pActionPeriod);
864
865 return 0;
866}
867
868/* Function header left blank Intentionally */
869static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
870 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
871{
872 tANI_U8 *inPtr = pValue;
873 int tempInt;
874 int v = 0;
875 char buf[32];
876 *pRate = 0;
877 *pTxFlags = 0;
878
879 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
880 /*no argument after the command*/
881 if (NULL == inPtr)
882 {
883 return -EINVAL;
884 }
885
886 /*no space after the command*/
887 else if (SPACE_ASCII_VALUE != *inPtr)
888 {
889 return -EINVAL;
890 }
891
892 /*removing empty spaces*/
893 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
894
895 /*no argument followed by spaces*/
896 if ('\0' == *inPtr)
897 {
898 return 0;
899 }
900
901 /*
902 * getting the first argument which sets multicast rate.
903 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530904 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530905 v = kstrtos32(buf, 10, &tempInt);
906 if ( v < 0)
907 {
908 return -EINVAL;
909 }
910
911 /*
912 * Validate the multicast rate.
913 */
914 switch (tempInt)
915 {
916 default:
917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
918 "Unsupported rate: %d", tempInt);
919 return -EINVAL;
920 case 0:
921 case 6:
922 case 9:
923 case 12:
924 case 18:
925 case 24:
926 case 36:
927 case 48:
928 case 54:
929 *pTxFlags = eHAL_TX_RATE_LEGACY;
930 *pRate = tempInt * 10;
931 break;
932 case 65:
933 *pTxFlags = eHAL_TX_RATE_HT20;
934 *pRate = tempInt * 10;
935 break;
936 case 72:
937 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
938 *pRate = 722; /* fractional rate 72.2 Mbps */
939 break;
940 }
941
942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
943 "Rate: %d", *pRate);
944
945 return 0;
946}
947
948/**---------------------------------------------------------------------------
949
950 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
951 Peer Info request
952
953 This is an asynchronous callback function from SME when the peer info
954 is received
955
956 \pUserData -> Adapter private data
957 \pPeerInfoRsp -> Peer info response
958
959 \return - 0 for success non-zero for failure
960 --------------------------------------------------------------------------*/
961static void
962hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
963{
964 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
965 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
966 hdd_station_ctx_t *pStaCtx;
967 v_U8_t i;
968
969 /*Sanity check*/
970 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
971 {
972 hddLog(LOGE,
973 FL("invalid adapter or adapter has invalid magic"));
974 return;
975 }
976
977 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
978 if (NULL != pStaCtx && NULL != pPeerInfo &&
979 eHAL_STATUS_SUCCESS == pPeerInfo->status)
980 {
981 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
982 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
983
984 /* Paranoia check */
985 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
986 {
987 for (i = 0; i < pPeerInfo->numPeers; i++)
988 {
989 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
990 &pPeerInfo->peerInfoParams[i],
991 sizeof(hdd_ibss_peer_info_params_t));
992 }
993 hddLog(LOG1,
994 FL("Peer Info copied in HDD"));
995 }
996 else
997 {
998 hddLog(LOGE,
999 FL(" Number of peers %d returned is more than limit %d"),
1000 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1001 }
1002 }
1003 else
1004 {
1005 hddLog(LOG1,
1006 FL("peerInfo returned is NULL"));
1007 }
1008
1009 complete(&pAdapter->ibss_peer_info_comp);
1010}
1011
1012/**---------------------------------------------------------------------------
1013
1014 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1015
1016 Request function to get IBSS peer info from lower layers
1017
1018 \pAdapter -> Adapter context
1019
1020 \return - 0 for success non-zero for failure
1021 --------------------------------------------------------------------------*/
1022static
1023VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1024{
1025 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1026 long status;
1027 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1028
1029 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1030
1031 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1032 hdd_cfg80211_get_ibss_peer_info_cb,
1033 VOS_TRUE, 0xFF);
1034
1035 if (VOS_STATUS_SUCCESS == retStatus)
1036 {
1037 status = wait_for_completion_interruptible_timeout
1038 (&pAdapter->ibss_peer_info_comp,
1039 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1040
1041 /* status will be 0 if timed out */
1042 if (status <= 0)
1043 {
1044 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1045 __func__, status);
1046 retStatus = VOS_STATUS_E_FAILURE;
1047 return retStatus;
1048 }
1049 }
1050 else
1051 {
1052 hddLog(VOS_TRACE_LEVEL_WARN,
1053 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1054 }
1055
1056 return retStatus;
1057}
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_cfg80211_get_ibss_peer_info() -
1062
1063 Request function to get IBSS peer info from lower layers
1064
1065 \pAdapter -> Adapter context
1066 \staIdx -> Sta index for which the peer info is requested
1067
1068 \return - 0 for success non-zero for failure
1069 --------------------------------------------------------------------------*/
1070static VOS_STATUS
1071hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1072{
1073 long status;
1074 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1075 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1076
1077 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1078
1079 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1080 hdd_cfg80211_get_ibss_peer_info_cb,
1081 VOS_FALSE, staIdx);
1082
1083 if (VOS_STATUS_SUCCESS == retStatus)
1084 {
1085 status = wait_for_completion_interruptible_timeout
1086 (&pAdapter->ibss_peer_info_comp,
1087 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1088
1089 /* status = 0 on timeout */
1090 if (status <= 0)
1091 {
1092 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1093 __func__, status);
1094 retStatus = VOS_STATUS_E_FAILURE;
1095 return retStatus;
1096 }
1097 }
1098 else
1099 {
1100 hddLog(VOS_TRACE_LEVEL_WARN,
1101 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1102 }
1103
1104 return retStatus;
1105}
1106
1107/* Function header left blank Intentionally */
1108VOS_STATUS
1109hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1110{
1111 tANI_U8 *inPtr = pValue;
1112 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1113
1114 /*no argument after the command*/
1115 if (NULL == inPtr)
1116 {
1117 return VOS_STATUS_E_FAILURE;;
1118 }
1119
1120 /*no space after the command*/
1121 else if (SPACE_ASCII_VALUE != *inPtr)
1122 {
1123 return VOS_STATUS_E_FAILURE;;
1124 }
1125
1126 /*removing empty spaces*/
1127 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1128
1129 /*no argument followed by spaces*/
1130 if ('\0' == *inPtr)
1131 {
1132 return VOS_STATUS_E_FAILURE;;
1133 }
1134
1135 /*getting the first argument ie the peer mac address */
1136 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1137 inPtr[11] != ':' || inPtr[14] != ':')
1138 {
1139 return VOS_STATUS_E_FAILURE;;
1140 }
1141 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1142 (unsigned int *)&pPeerMacAddr->bytes[0],
1143 (unsigned int *)&pPeerMacAddr->bytes[1],
1144 (unsigned int *)&pPeerMacAddr->bytes[2],
1145 (unsigned int *)&pPeerMacAddr->bytes[3],
1146 (unsigned int *)&pPeerMacAddr->bytes[4],
1147 (unsigned int *)&pPeerMacAddr->bytes[5]);
1148
1149 /* The command buffer seems to be fine */
1150 return VOS_STATUS_SUCCESS;
1151}
1152
1153/* Function header left blank Intentionally */
1154static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1155 tANI_U32 limit)
1156{
1157 tANI_U8 len;
1158 tANI_U8 data;
1159
1160 /* skip white space */
1161 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1162 {
1163 command++;
1164 limit--;
1165 }
1166
1167 /* skip element id and element length */
1168 len = 2;
1169
1170 /* extract oui */
1171 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1172 (limit > 1))
1173 {
1174 /* Convert ASCII to decimal */
1175 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1176 ie[len++] = data;
1177 command += 2;
1178 limit -= 2;
1179 }
1180
1181 /* skip white space */
1182 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1183 {
1184 command++;
1185 limit--;
1186 }
1187
1188 /* extract data */
1189 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1190 (limit > 1))
1191 {
1192 /* Convert ASCII to decimal */
1193 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1194 ie[len++] = data;
1195 command += 2;
1196 limit -= 2;
1197 }
1198
1199 /* fill element id and element length */
1200 ie[0] = IE_EID_VENDOR;
1201 ie[1] = len - 2;
1202
1203 return len;
1204}
1205
1206static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1207{
1208 tANI_U32 ieLenPresent = 0;
1209 int left = addIeLen;
1210 v_U8_t *ptr = addIePtr;
1211 v_U8_t elem_id,elem_len;
1212
1213 while(left >= 2)
1214 {
1215 elem_id = ptr[0];
1216 elem_len = ptr[1];
1217 left -= 2;
1218 if(elem_len > left)
1219 {
1220 hddLog(LOGE,
1221 FL("****Invalid elem_len=%d left=%d*****"),
1222 elem_len,left);
1223 return 0;
1224 }
1225 if ((elem_id == IE_EID_VENDOR) &&
1226 (left >= WPA_OUI_TYPE_SIZE))
1227 {
1228 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1229 WPA_OUI_TYPE_SIZE))
1230 {
1231 ieLenPresent += elem_len + 2;
1232 return ieLenPresent;
1233 }
1234 }
1235 ieLenPresent += (elem_len + 2);
1236 left -= elem_len;
1237 ptr += (elem_len + 2);
1238 }
1239 return 0;
1240}
1241
1242#endif /* WLAN_FEATURE_RMC */
1243
Rajeev79dbe4c2013-10-05 11:03:42 +05301244#ifdef FEATURE_WLAN_BATCH_SCAN
1245
1246/**---------------------------------------------------------------------------
1247
1248 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1249 input string
1250
1251 This function extracts assigned integer from string in below format:
1252 "STRING=10" : extracts integer 10 from this string
1253
1254 \param - pInPtr Pointer to input string
1255 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1256 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1257 assigned
1258 \param - pLastArg to tell whether it is last arguement in input string or
1259 not
1260
1261 \return - NULL for failure cases
1262 pointer to next arguement in input string for success cases
1263 --------------------------------------------------------------------------*/
1264static tANI_U8 *
1265hdd_extract_assigned_int_from_str
1266(
1267 tANI_U8 *pInPtr,
1268 tANI_U8 base,
1269 tANI_U32 *pOutPtr,
1270 tANI_U8 *pLastArg
1271)
1272{
1273 int tempInt;
1274 int v = 0;
1275 char buf[32];
1276 int val = 0;
1277 *pLastArg = FALSE;
1278
1279 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1280 if (NULL == pInPtr)
1281 {
1282 return NULL;
1283 }
1284
1285 pInPtr++;
1286
1287 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1288
1289 val = sscanf(pInPtr, "%32s ", buf);
1290 if (val < 0 && val > strlen(pInPtr))
1291 {
1292 return NULL;
1293 }
1294 pInPtr += val;
1295 v = kstrtos32(buf, base, &tempInt);
1296 if (v < 0)
1297 {
1298 return NULL;
1299 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001300 if (tempInt < 0)
1301 {
1302 tempInt = 0;
1303 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301304 *pOutPtr = tempInt;
1305
1306 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1307 if (NULL == pInPtr)
1308 {
1309 *pLastArg = TRUE;
1310 return NULL;
1311 }
1312 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1313
1314 return pInPtr;
1315}
1316
1317/**---------------------------------------------------------------------------
1318
1319 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1320 input string
1321
1322 This function extracts assigned character from string in below format:
1323 "STRING=A" : extracts char 'A' from this string
1324
1325 \param - pInPtr Pointer to input string
1326 \param - pOutPtr Pointer to variable in which extracted char needs to be
1327 assigned
1328 \param - pLastArg to tell whether it is last arguement in input string or
1329 not
1330
1331 \return - NULL for failure cases
1332 pointer to next arguement in input string for success cases
1333 --------------------------------------------------------------------------*/
1334static tANI_U8 *
1335hdd_extract_assigned_char_from_str
1336(
1337 tANI_U8 *pInPtr,
1338 tANI_U8 *pOutPtr,
1339 tANI_U8 *pLastArg
1340)
1341{
1342 *pLastArg = FALSE;
1343
1344 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1345 if (NULL == pInPtr)
1346 {
1347 return NULL;
1348 }
1349
1350 pInPtr++;
1351
1352 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1353
1354 *pOutPtr = *pInPtr;
1355
1356 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1357 if (NULL == pInPtr)
1358 {
1359 *pLastArg = TRUE;
1360 return NULL;
1361 }
1362 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1363
1364 return pInPtr;
1365}
1366
1367
1368/**---------------------------------------------------------------------------
1369
1370 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1371
1372 This function parses set batch scan command in below format:
1373 WLS_BATCHING_SET <space> followed by below arguements
1374 "SCANFREQ=XX" : Optional defaults to 30 sec
1375 "MSCAN=XX" : Required number of scans to attempt to batch
1376 "BESTN=XX" : Best Network (RSSI) defaults to 16
1377 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1378 A. implies only 5 GHz , B. implies only 2.4GHz
1379 "RTT=X" : optional defaults to 0
1380 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1381 error
1382
1383 For example input commands:
1384 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1385 translated into set batch scan with following parameters:
1386 a) Frequence 60 seconds
1387 b) Batch 10 scans together
1388 c) Best RSSI to be 20
1389 d) 5GHz band only
1390 e) RTT is equal to 0
1391
1392 \param - pValue Pointer to input channel list
1393 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1394
1395 \return - 0 for success non-zero for failure
1396
1397 --------------------------------------------------------------------------*/
1398static int
1399hdd_parse_set_batchscan_command
1400(
1401 tANI_U8 *pValue,
1402 tSirSetBatchScanReq *pHddSetBatchScanReq
1403)
1404{
1405 tANI_U8 *inPtr = pValue;
1406 tANI_U8 val = 0;
1407 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301408 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001409 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301410 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1411 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1412 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001413 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301414
Rajeev79dbe4c2013-10-05 11:03:42 +05301415 /*go to space after WLS_BATCHING_SET command*/
1416 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1417 /*no argument after the command*/
1418 if (NULL == inPtr)
1419 {
1420 return -EINVAL;
1421 }
1422
1423 /*no space after the command*/
1424 else if (SPACE_ASCII_VALUE != *inPtr)
1425 {
1426 return -EINVAL;
1427 }
1428
1429 /*removing empty spaces*/
1430 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1431
1432 /*no argument followed by spaces*/
1433 if ('\0' == *inPtr)
1434 {
1435 return -EINVAL;
1436 }
1437
1438 /*check and parse SCANFREQ*/
1439 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1440 {
1441 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001442 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001443
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001445 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001446 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001447 }
1448
Rajeev79dbe4c2013-10-05 11:03:42 +05301449 if ( (NULL == inPtr) || (TRUE == lastArg))
1450 {
1451 return -EINVAL;
1452 }
1453 }
1454
1455 /*check and parse MSCAN*/
1456 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1457 {
1458 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001459 &nMscan, &lastArg);
1460
1461 if (0 == nMscan)
1462 {
1463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1464 "invalid MSCAN=%d", nMscan);
1465 return -EINVAL;
1466 }
1467
Rajeev79dbe4c2013-10-05 11:03:42 +05301468 if (TRUE == lastArg)
1469 {
1470 goto done;
1471 }
1472 else if (NULL == inPtr)
1473 {
1474 return -EINVAL;
1475 }
1476 }
1477 else
1478 {
1479 return -EINVAL;
1480 }
1481
1482 /*check and parse BESTN*/
1483 if ((strncmp(inPtr, "BESTN", 5) == 0))
1484 {
1485 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001486 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001487
Rajeev Kumarc933d982013-11-18 20:04:20 -08001488 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001489 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001490 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001491 }
1492
Rajeev79dbe4c2013-10-05 11:03:42 +05301493 if (TRUE == lastArg)
1494 {
1495 goto done;
1496 }
1497 else if (NULL == inPtr)
1498 {
1499 return -EINVAL;
1500 }
1501 }
1502
1503 /*check and parse CHANNEL*/
1504 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1505 {
1506 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001507
Rajeev79dbe4c2013-10-05 11:03:42 +05301508 if (('A' == val) || ('a' == val))
1509 {
c_hpothuebf89732014-02-25 13:00:24 +05301510 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301511 }
1512 else if (('B' == val) || ('b' == val))
1513 {
c_hpothuebf89732014-02-25 13:00:24 +05301514 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 }
1516 else
1517 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001518 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1519 }
1520
1521 if (TRUE == lastArg)
1522 {
1523 goto done;
1524 }
1525 else if (NULL == inPtr)
1526 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301527 return -EINVAL;
1528 }
1529 }
1530
1531 /*check and parse RTT*/
1532 if ((strncmp(inPtr, "RTT", 3) == 0))
1533 {
1534 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001535 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301536 if (TRUE == lastArg)
1537 {
1538 goto done;
1539 }
1540 if (NULL == inPtr)
1541 {
1542 return -EINVAL;
1543 }
1544 }
1545
1546
1547done:
1548
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001549 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1550 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1551 pHddSetBatchScanReq->bestNetwork = nBestN;
1552 pHddSetBatchScanReq->rfBand = ucRfBand;
1553 pHddSetBatchScanReq->rtt = nRtt;
1554
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1556 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1557 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1558 pHddSetBatchScanReq->scanFrequency,
1559 pHddSetBatchScanReq->numberOfScansToBatch,
1560 pHddSetBatchScanReq->bestNetwork,
1561 pHddSetBatchScanReq->rfBand,
1562 pHddSetBatchScanReq->rtt);
1563
1564 return 0;
1565}/*End of hdd_parse_set_batchscan_command*/
1566
1567/**---------------------------------------------------------------------------
1568
1569 \brief hdd_set_batch_scan_req_callback () - This function is called after
1570 receiving set batch scan response from FW and it saves set batch scan
1571 response data FW to HDD context and sets the completion event on
1572 which hdd_ioctl is waiting
1573
1574 \param - callbackContext Pointer to HDD adapter
1575 \param - pRsp Pointer to set batch scan response data received from FW
1576
1577 \return - nothing
1578
1579 --------------------------------------------------------------------------*/
1580static void hdd_set_batch_scan_req_callback
1581(
1582 void *callbackContext,
1583 tSirSetBatchScanRsp *pRsp
1584)
1585{
1586 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1587 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1588
1589 /*sanity check*/
1590 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1591 {
1592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1593 "%s: Invalid pAdapter magic", __func__);
1594 VOS_ASSERT(0);
1595 return;
1596 }
1597 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1598
1599 /*save set batch scan response*/
1600 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1601
1602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1603 "Received set batch scan rsp from FW with nScansToBatch=%d",
1604 pHddSetBatchScanRsp->nScansToBatch);
1605
1606 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1607 complete(&pAdapter->hdd_set_batch_scan_req_var);
1608
1609 return;
1610}/*End of hdd_set_batch_scan_req_callback*/
1611
1612
1613/**---------------------------------------------------------------------------
1614
1615 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1616 info in hdd batch scan response queue
1617
1618 \param - pAdapter Pointer to hdd adapter
1619 \param - pAPMetaInfo Pointer to access point meta info
1620 \param - scanId scan ID of batch scan response
1621 \param - isLastAp tells whether AP is last AP in batch scan response or not
1622
1623 \return - nothing
1624
1625 --------------------------------------------------------------------------*/
1626static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1627 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1628{
1629 tHddBatchScanRsp *pHead;
1630 tHddBatchScanRsp *pNode;
1631 tHddBatchScanRsp *pPrev;
1632 tHddBatchScanRsp *pTemp;
1633 tANI_U8 ssidLen;
1634
1635 /*head of hdd batch scan response queue*/
1636 pHead = pAdapter->pBatchScanRsp;
1637
1638 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1639 if (NULL == pNode)
1640 {
1641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1642 "%s: Could not allocate memory", __func__);
1643 VOS_ASSERT(0);
1644 return;
1645 }
1646
1647 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1648 sizeof(pNode->ApInfo.bssid));
1649 ssidLen = strlen(pApMetaInfo->ssid);
1650 if (SIR_MAX_SSID_SIZE < ssidLen)
1651 {
1652 /*invalid scan result*/
1653 vos_mem_free(pNode);
1654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1655 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1656 return;
1657 }
1658 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1659 /*null terminate ssid*/
1660 pNode->ApInfo.ssid[ssidLen] = '\0';
1661 pNode->ApInfo.ch = pApMetaInfo->ch;
1662 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1663 pNode->ApInfo.age = pApMetaInfo->timestamp;
1664 pNode->ApInfo.batchId = scanId;
1665 pNode->ApInfo.isLastAp = isLastAp;
1666
1667 pNode->pNext = NULL;
1668 if (NULL == pHead)
1669 {
1670 pAdapter->pBatchScanRsp = pNode;
1671 }
1672 else
1673 {
1674 pTemp = pHead;
1675 while (NULL != pTemp)
1676 {
1677 pPrev = pTemp;
1678 pTemp = pTemp->pNext;
1679 }
1680 pPrev->pNext = pNode;
1681 }
1682
1683 return;
1684}/*End of hdd_populate_batch_scan_rsp_queue*/
1685
1686/**---------------------------------------------------------------------------
1687
1688 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1689 receiving batch scan response indication from FW. It saves get batch scan
1690 response data in HDD batch scan response queue. This callback sets the
1691 completion event on which hdd_ioctl is waiting only after getting complete
1692 batch scan response data from FW
1693
1694 \param - callbackContext Pointer to HDD adapter
1695 \param - pRsp Pointer to get batch scan response data received from FW
1696
1697 \return - nothing
1698
1699 --------------------------------------------------------------------------*/
1700static void hdd_batch_scan_result_ind_callback
1701(
1702 void *callbackContext,
1703 void *pRsp
1704)
1705{
1706 v_BOOL_t isLastAp;
1707 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001708 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301709 tANI_U32 numberScanList;
1710 tANI_U32 nextScanListOffset;
1711 tANI_U32 nextApMetaInfoOffset;
1712 hdd_adapter_t* pAdapter;
1713 tpSirBatchScanList pScanList;
1714 tpSirBatchScanNetworkInfo pApMetaInfo;
1715 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1716 tSirSetBatchScanReq *pReq;
1717
1718 pAdapter = (hdd_adapter_t *)callbackContext;
1719 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001720 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301721 {
1722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1723 "%s: Invalid pAdapter magic", __func__);
1724 VOS_ASSERT(0);
1725 return;
1726 }
1727
1728 /*initialize locals*/
1729 pReq = &pAdapter->hddSetBatchScanReq;
1730 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1731 isLastAp = FALSE;
1732 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001733 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301734 numberScanList = 0;
1735 nextScanListOffset = 0;
1736 nextApMetaInfoOffset = 0;
1737 pScanList = NULL;
1738 pApMetaInfo = NULL;
1739
1740 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1741 {
1742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001743 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301744 isLastAp = TRUE;
1745 goto done;
1746 }
1747
1748 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "Batch scan rsp: numberScalList %d", numberScanList);
1751
1752 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1753 {
1754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "%s: numberScanList %d", __func__, numberScanList);
1756 isLastAp = TRUE;
1757 goto done;
1758 }
1759
1760 while (numberScanList)
1761 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001762 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301763 nextScanListOffset);
1764 if (NULL == pScanList)
1765 {
1766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001767 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 isLastAp = TRUE;
1769 goto done;
1770 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001771 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001773 "Batch scan rsp: numApMetaInfo %d scanId %d",
1774 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301775
1776 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1777 {
1778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1779 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1780 isLastAp = TRUE;
1781 goto done;
1782 }
1783
Rajeev Kumarce651e42013-10-21 18:57:15 -07001784 /*Initialize next AP meta info offset for next scan list*/
1785 nextApMetaInfoOffset = 0;
1786
Rajeev79dbe4c2013-10-05 11:03:42 +05301787 while (numApMetaInfo)
1788 {
1789 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1790 nextApMetaInfoOffset);
1791 if (NULL == pApMetaInfo)
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001794 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301795 isLastAp = TRUE;
1796 goto done;
1797 }
1798 /*calculate AP age*/
1799 pApMetaInfo->timestamp =
1800 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1801
1802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001803 "%s: bssId "MAC_ADDRESS_STR
1804 " ch %d rssi %d timestamp %d", __func__,
1805 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1806 pApMetaInfo->ch, pApMetaInfo->rssi,
1807 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301808
1809 /*mark last AP in batch scan response*/
1810 if ((TRUE == pBatchScanRsp->isLastResult) &&
1811 (1 == numberScanList) && (1 == numApMetaInfo))
1812 {
1813 isLastAp = TRUE;
1814 }
1815
1816 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1817 /*store batch scan repsonse in hdd queue*/
1818 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1819 pScanList->scanId, isLastAp);
1820 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1821
1822 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1823 numApMetaInfo--;
1824 }
1825
Rajeev Kumarce651e42013-10-21 18:57:15 -07001826 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1827 + (sizeof(tSirBatchScanNetworkInfo)
1828 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301829 numberScanList--;
1830 }
1831
1832done:
1833
1834 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1835 requested from hdd_ioctl*/
1836 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1837 (TRUE == isLastAp))
1838 {
1839 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1840 complete(&pAdapter->hdd_get_batch_scan_req_var);
1841 }
1842
1843 return;
1844}/*End of hdd_batch_scan_result_ind_callback*/
1845
1846/**---------------------------------------------------------------------------
1847
1848 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1849 response as per batch scan FR request format by putting proper markers
1850
1851 \param - pDest pointer to destination buffer
1852 \param - cur_len current length
1853 \param - tot_len total remaining size which can be written to user space
1854 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1855 \param - pAdapter Pointer to HDD adapter
1856
1857 \return - ret no of characters written
1858
1859 --------------------------------------------------------------------------*/
1860static tANI_U32
1861hdd_format_batch_scan_rsp
1862(
1863 tANI_U8 *pDest,
1864 tANI_U32 cur_len,
1865 tANI_U32 tot_len,
1866 tHddBatchScanRsp *pApMetaInfo,
1867 hdd_adapter_t* pAdapter
1868)
1869{
1870 tANI_U32 ret = 0;
1871 tANI_U32 rem_len = 0;
1872 tANI_U8 temp_len = 0;
1873 tANI_U8 temp_total_len = 0;
1874 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1875 tANI_U8 *pTemp = temp;
1876
1877 /*Batch scan reponse needs to be returned to user space in
1878 following format:
1879 "scancount=X\n" where X is the number of scans in current batch
1880 batch
1881 "trunc\n" optional present if current scan truncated
1882 "bssid=XX:XX:XX:XX:XX:XX\n"
1883 "ssid=XXXX\n"
1884 "freq=X\n" frequency in Mhz
1885 "level=XX\n"
1886 "age=X\n" ms
1887 "dist=X\n" cm (-1 if not available)
1888 "errror=X\n" (-1if not available)
1889 "====\n" (end of ap marker)
1890 "####\n" (end of scan marker)
1891 "----\n" (end of results)*/
1892 /*send scan result in above format to user space based on
1893 available length*/
1894 /*The GET response may have more data than the driver can return in its
1895 buffer. In that case the buffer should be filled to the nearest complete
1896 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1897 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1898 The final buffer should end with "----\n"*/
1899
1900 /*sanity*/
1901 if (cur_len > tot_len)
1902 {
1903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1904 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1905 return 0;
1906 }
1907 else
1908 {
1909 rem_len = (tot_len - cur_len);
1910 }
1911
1912 /*end scan marker*/
1913 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1914 {
1915 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1916 pTemp += temp_len;
1917 temp_total_len += temp_len;
1918 }
1919
1920 /*bssid*/
1921 temp_len = snprintf(pTemp, sizeof(temp),
1922 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1923 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1924 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1925 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1926 pTemp += temp_len;
1927 temp_total_len += temp_len;
1928
1929 /*ssid*/
1930 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1931 pApMetaInfo->ApInfo.ssid);
1932 pTemp += temp_len;
1933 temp_total_len += temp_len;
1934
1935 /*freq*/
1936 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001937 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301938 pTemp += temp_len;
1939 temp_total_len += temp_len;
1940
1941 /*level*/
1942 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1943 pApMetaInfo->ApInfo.rssi);
1944 pTemp += temp_len;
1945 temp_total_len += temp_len;
1946
1947 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001948 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301949 pApMetaInfo->ApInfo.age);
1950 pTemp += temp_len;
1951 temp_total_len += temp_len;
1952
1953 /*dist*/
1954 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1955 pTemp += temp_len;
1956 temp_total_len += temp_len;
1957
1958 /*error*/
1959 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1960 pTemp += temp_len;
1961 temp_total_len += temp_len;
1962
1963 /*end AP marker*/
1964 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1965 pTemp += temp_len;
1966 temp_total_len += temp_len;
1967
1968 /*last AP in batch scan response*/
1969 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1970 {
1971 /*end scan marker*/
1972 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*end batch scan result marker*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001980
Rajeev79dbe4c2013-10-05 11:03:42 +05301981 }
1982
1983 if (temp_total_len < rem_len)
1984 {
1985 ret = temp_total_len + 1;
1986 strlcpy(pDest, temp, ret);
1987 pAdapter->isTruncated = FALSE;
1988 }
1989 else
1990 {
1991 pAdapter->isTruncated = TRUE;
1992 if (rem_len >= strlen("%%%%"))
1993 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001994 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301995 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001996 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301997 {
1998 ret = 0;
1999 }
2000 }
2001
2002 return ret;
2003
2004}/*End of hdd_format_batch_scan_rsp*/
2005
2006/**---------------------------------------------------------------------------
2007
2008 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2009 buffer starting with head of hdd batch scan response queue
2010
2011 \param - pAdapter Pointer to HDD adapter
2012 \param - pDest Pointer to user data buffer
2013 \param - cur_len current offset in user buffer
2014 \param - rem_len remaining no of bytes in user buffer
2015
2016 \return - number of bytes written in user buffer
2017
2018 --------------------------------------------------------------------------*/
2019
2020tANI_U32 hdd_populate_user_batch_scan_rsp
2021(
2022 hdd_adapter_t* pAdapter,
2023 tANI_U8 *pDest,
2024 tANI_U32 cur_len,
2025 tANI_U32 rem_len
2026)
2027{
2028 tHddBatchScanRsp *pHead;
2029 tHddBatchScanRsp *pPrev;
2030 tANI_U32 len;
2031
Rajeev79dbe4c2013-10-05 11:03:42 +05302032 pAdapter->isTruncated = FALSE;
2033
2034 /*head of hdd batch scan response queue*/
2035 pHead = pAdapter->pBatchScanRsp;
2036 while (pHead)
2037 {
2038 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2039 pAdapter);
2040 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002041 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302042 cur_len += len;
2043 if(TRUE == pAdapter->isTruncated)
2044 {
2045 /*result is truncated return rest of scan rsp in next req*/
2046 cur_len = rem_len;
2047 break;
2048 }
2049 pPrev = pHead;
2050 pHead = pHead->pNext;
2051 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002052 if (TRUE == pPrev->ApInfo.isLastAp)
2053 {
2054 pAdapter->prev_batch_id = 0;
2055 }
2056 else
2057 {
2058 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2059 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302060 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002061 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302062 }
2063
2064 return cur_len;
2065}/*End of hdd_populate_user_batch_scan_rsp*/
2066
2067/**---------------------------------------------------------------------------
2068
2069 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2070 scan response data from HDD queue to user space
2071 It does following in detail:
2072 a) if HDD has enough data in its queue then it 1st copies data to user
2073 space and then send get batch scan indication message to FW. In this
2074 case it does not wait on any event and batch scan response data will
2075 be populated in HDD response queue in MC thread context after receiving
2076 indication from FW
2077 b) else send get batch scan indication message to FW and wait on an event
2078 which will be set once HDD receives complete batch scan response from
2079 FW and then this function returns batch scan response to user space
2080
2081 \param - pAdapter Pointer to HDD adapter
2082 \param - pPrivData Pointer to priv_data
2083
2084 \return - 0 for success -EFAULT for failure
2085
2086 --------------------------------------------------------------------------*/
2087
2088int hdd_return_batch_scan_rsp_to_user
2089(
2090 hdd_adapter_t* pAdapter,
2091 hdd_priv_data_t *pPrivData,
2092 tANI_U8 *command
2093)
2094{
2095 tANI_U8 *pDest;
2096 tANI_U32 count = 0;
2097 tANI_U32 len = 0;
2098 tANI_U32 cur_len = 0;
2099 tANI_U32 rem_len = 0;
2100 eHalStatus halStatus;
2101 unsigned long rc;
2102 tSirTriggerBatchScanResultInd *pReq;
2103
2104 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2105 pReq->param = 0;/*batch scan client*/
2106 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2107 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2108
2109 cur_len = pPrivData->used_len;
2110 if (pPrivData->total_len > pPrivData->used_len)
2111 {
2112 rem_len = pPrivData->total_len - pPrivData->used_len;
2113 }
2114 else
2115 {
2116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2117 "%s: Invalid user data buffer total_len %d used_len %d",
2118 __func__, pPrivData->total_len, pPrivData->used_len);
2119 return -EFAULT;
2120 }
2121
2122 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2123 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2124 cur_len, rem_len);
2125 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2126
2127 /*enough scan result available in cache to return to user space or
2128 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002129 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302130 {
2131 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2132 halStatus = sme_TriggerBatchScanResultInd(
2133 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2134 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2135 pAdapter);
2136 if ( eHAL_STATUS_SUCCESS == halStatus )
2137 {
2138 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2139 {
2140 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2141 rc = wait_for_completion_timeout(
2142 &pAdapter->hdd_get_batch_scan_req_var,
2143 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302144 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302145 {
2146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302147 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2148 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302149 return -EFAULT;
2150 }
2151 }
2152
2153 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002154 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302155 pDest += len;
2156 cur_len += len;
2157
2158 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2159 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2160 cur_len, rem_len);
2161 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2162
2163 count = 0;
2164 len = (len - pPrivData->used_len);
2165 pDest = (command + pPrivData->used_len);
2166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002167 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302168 while(count < len)
2169 {
2170 printk("%c", *(pDest + count));
2171 count++;
2172 }
2173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2174 "%s: copy %d data to user buffer", __func__, len);
2175 if (copy_to_user(pPrivData->buf, pDest, len))
2176 {
2177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2178 "%s: failed to copy data to user buffer", __func__);
2179 return -EFAULT;
2180 }
2181 }
2182 else
2183 {
2184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2185 "sme_GetBatchScanScan returned failure halStatus %d",
2186 halStatus);
2187 return -EINVAL;
2188 }
2189 }
2190 else
2191 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302192 count = 0;
2193 len = (len - pPrivData->used_len);
2194 pDest = (command + pPrivData->used_len);
2195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002196 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 while(count < len)
2198 {
2199 printk("%c", *(pDest + count));
2200 count++;
2201 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2203 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302204 if (copy_to_user(pPrivData->buf, pDest, len))
2205 {
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2207 "%s: failed to copy data to user buffer", __func__);
2208 return -EFAULT;
2209 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302210 }
2211
2212 return 0;
2213} /*End of hdd_return_batch_scan_rsp_to_user*/
2214
Rajeev Kumar8b373292014-01-08 20:36:55 -08002215/**---------------------------------------------------------------------------
2216
2217 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2218 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2219 WLS_BATCHING VERSION
2220 WLS_BATCHING SET
2221 WLS_BATCHING GET
2222 WLS_BATCHING STOP
2223
2224 \param - pAdapter Pointer to HDD adapter
2225 \param - pPrivdata Pointer to priv_data
2226 \param - command Pointer to command
2227
2228 \return - 0 for success -EFAULT for failure
2229
2230 --------------------------------------------------------------------------*/
2231
2232int hdd_handle_batch_scan_ioctl
2233(
2234 hdd_adapter_t *pAdapter,
2235 hdd_priv_data_t *pPrivdata,
2236 tANI_U8 *command
2237)
2238{
2239 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002240 hdd_context_t *pHddCtx;
2241
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302242 ENTER();
2243
Yue Mae36e3552014-03-05 17:06:20 -08002244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2245 ret = wlan_hdd_validate_context(pHddCtx);
2246 if (ret)
2247 {
Yue Mae36e3552014-03-05 17:06:20 -08002248 goto exit;
2249 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002250
2251 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2252 {
2253 char extra[32];
2254 tANI_U8 len = 0;
2255 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2256
2257 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2258 {
2259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2260 "%s: Batch scan feature is not supported by FW", __func__);
2261 ret = -EINVAL;
2262 goto exit;
2263 }
2264
2265 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2266 version);
2267 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2268 {
2269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2270 "%s: failed to copy data to user buffer", __func__);
2271 ret = -EFAULT;
2272 goto exit;
2273 }
2274 ret = HDD_BATCH_SCAN_VERSION;
2275 }
2276 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2277 {
2278 int status;
2279 tANI_U8 *value = (command + 16);
2280 eHalStatus halStatus;
2281 unsigned long rc;
2282 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2283 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2284
2285 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2286 {
2287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2288 "%s: Batch scan feature is not supported by FW", __func__);
2289 ret = -EINVAL;
2290 goto exit;
2291 }
2292
2293 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2294 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2295 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2296 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302299 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002300 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302301 hdd_device_modetoString(pAdapter->device_mode),
2302 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002303 ret = -EINVAL;
2304 goto exit;
2305 }
2306
2307 status = hdd_parse_set_batchscan_command(value, pReq);
2308 if (status)
2309 {
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "Invalid WLS_BATCHING SET command");
2312 ret = -EINVAL;
2313 goto exit;
2314 }
2315
2316
2317 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2318 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2319 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2320 pAdapter);
2321
2322 if ( eHAL_STATUS_SUCCESS == halStatus )
2323 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302324 char extra[32];
2325 tANI_U8 len = 0;
2326 tANI_U8 mScan = 0;
2327
Rajeev Kumar8b373292014-01-08 20:36:55 -08002328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2329 "sme_SetBatchScanReq returned success halStatus %d",
2330 halStatus);
2331 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2332 {
2333 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2334 rc = wait_for_completion_timeout(
2335 &pAdapter->hdd_set_batch_scan_req_var,
2336 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2337 if (0 == rc)
2338 {
2339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2340 "%s: Timeout waiting for set batch scan to complete",
2341 __func__);
2342 ret = -EINVAL;
2343 goto exit;
2344 }
2345 }
2346 if ( !pRsp->nScansToBatch )
2347 {
2348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2349 "%s: Received set batch scan failure response from FW",
2350 __func__);
2351 ret = -EINVAL;
2352 goto exit;
2353 }
2354 /*As per the Batch Scan Framework API we should return the MIN of
2355 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302356 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002357
2358 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2359
2360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2361 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302362 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2363 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2364 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2365 {
2366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2367 "%s: failed to copy MSCAN value to user buffer", __func__);
2368 ret = -EFAULT;
2369 goto exit;
2370 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002371 }
2372 else
2373 {
2374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2375 "sme_SetBatchScanReq returned failure halStatus %d",
2376 halStatus);
2377 ret = -EINVAL;
2378 goto exit;
2379 }
2380 }
2381 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2382 {
2383 eHalStatus halStatus;
2384 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2385 pInd->param = 0;
2386
2387 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2388 {
2389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2390 "%s: Batch scan feature is not supported by FW", __func__);
2391 ret = -EINVAL;
2392 goto exit;
2393 }
2394
2395 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2396 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002398 "Batch scan is not yet enabled batch scan state %d",
2399 pAdapter->batchScanState);
2400 ret = -EINVAL;
2401 goto exit;
2402 }
2403
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002404 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2405 hdd_deinit_batch_scan(pAdapter);
2406 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2407
Rajeev Kumar8b373292014-01-08 20:36:55 -08002408 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2409
2410 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2411 pAdapter->sessionId);
2412 if ( eHAL_STATUS_SUCCESS == halStatus )
2413 {
2414 ret = 0;
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2416 "sme_StopBatchScanInd returned success halStatus %d",
2417 halStatus);
2418 }
2419 else
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "sme_StopBatchScanInd returned failure halStatus %d",
2423 halStatus);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427 }
2428 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2429 {
2430 tANI_U32 remain_len;
2431
2432 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2433 {
2434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2435 "%s: Batch scan feature is not supported by FW", __func__);
2436 ret = -EINVAL;
2437 goto exit;
2438 }
2439
2440 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2441 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002443 "Batch scan is not yet enabled could not return results"
2444 "Batch Scan state %d",
2445 pAdapter->batchScanState);
2446 ret = -EINVAL;
2447 goto exit;
2448 }
2449
2450 pPrivdata->used_len = 16;
2451 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2452 if (remain_len < pPrivdata->total_len)
2453 {
2454 /*Clear previous batch scan response data if any*/
2455 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2456 }
2457 else
2458 {
2459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2460 "Invalid total length from user space can't fetch batch"
2461 " scan response total_len %d used_len %d remain len %d",
2462 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2463 ret = -EINVAL;
2464 goto exit;
2465 }
2466 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2467 }
2468
2469exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302470 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002471 return ret;
2472}
2473
2474
Rajeev79dbe4c2013-10-05 11:03:42 +05302475#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2476
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302477#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2478/**
2479 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2480 * to Handoff request
2481 * @handoffInfo: Pointer to Handoff request
2482 * @src: enum of handoff_src
2483 * Return: None
2484 */
2485#ifndef QCA_WIFI_ISOC
2486static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2487 *handoffInfo, handoff_src src)
2488{
2489 handoffInfo->src = src;
2490}
2491#else
2492static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2493 *handoffInfo, handoff_src src)
2494{
2495}
2496#endif
2497
2498/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302499 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302500 *
2501 * @pAdapter: Adapter upon which the command was received
2502 * @bssid: BSSID with which to reassociate
2503 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302504 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302505 *
2506 * Return: 0 for success non-zero for failure
2507 */
2508#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302509int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302510 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302511{
2512 hdd_station_ctx_t *pHddStaCtx;
2513 tCsrHandoffRequest handoffInfo;
2514 hdd_context_t *pHddCtx = NULL;
2515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2516
2517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2518
2519 /* if not associated, no need to proceed with reassoc */
2520 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2521 hddLog(LOG1, FL("Not associated"));
2522 return -EINVAL;
2523 }
2524
2525 /* if the target bssid is same as currently associated AP,
2526 then no need to proceed with reassoc */
2527 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2528 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2529 return -EINVAL;
2530 }
2531
2532 /* Check channel number is a valid channel number */
2533 if (VOS_STATUS_SUCCESS !=
2534 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2535 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2536 return -EINVAL;
2537 }
2538
2539 /* Proceed with reassoc */
2540 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302541 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302542 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2543 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2544 return 0;
2545}
2546#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302547int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302548 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302549{
2550 return -EPERM;
2551}
2552#endif
2553
2554/**
2555 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2556 * This function parses the v1 REASSOC command with the format
2557 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2558 * Hex-ASCII representation of the BSSID and CH is the ASCII
2559 * representation of the channel. For example
2560 * REASSOC 00:0a:0b:11:22:33 48
2561 *
2562 * @pAdapter: Adapter upon which the command was received
2563 * @command: ASCII text command that was received
2564 *
2565 * Return: 0 for success non-zero for failure
2566 */
2567static int
2568hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2569{
2570 tANI_U8 channel = 0;
2571 tSirMacAddr bssid;
2572 int ret;
2573
2574 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2575 if (ret)
2576 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2577 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302578 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302579
2580 return ret;
2581}
2582
2583/**
2584 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2585 * This function parses the v2 REASSOC command with the format
2586 * REASSOC <android_wifi_reassoc_params>
2587 *
2588 * @pAdapter: Adapter upon which the command was received
2589 * @command: command that was received, ASCII command followed
2590 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302591 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302592 *
2593 * Return: 0 for success non-zero for failure
2594 */
2595static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302596hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2597 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302598{
2599 struct android_wifi_reassoc_params params;
2600 tSirMacAddr bssid;
2601 int ret;
2602
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302603 if (total_len < sizeof(params) + 8) {
2604 hddLog(LOGE, FL("Invalid command length"));
2605 return -EINVAL;
2606 }
2607
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302608 /* The params are located after "REASSOC " */
2609 memcpy(&params, command + 8, sizeof(params));
2610
2611 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2612 hddLog(LOGE, FL("MAC address parsing failed"));
2613 ret = -EINVAL;
2614 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302615 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302616 }
2617 return ret;
2618}
2619
2620/**
2621 * hdd_parse_reassoc() - parse the REASSOC command
2622 * There are two different versions of the REASSOC command.Version 1
2623 * of the command contains a parameter list that is ASCII characters
2624 * whereas version 2 contains a combination of ASCII and binary
2625 * payload. Determine if a version 1 or a version 2 command is being
2626 * parsed by examining the parameters, and then dispatch the parser
2627 * that is appropriate for the command.
2628 *
2629 * @pAdapter: Adapter upon which the command was received
2630 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302631 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302632 *
2633 * Return: 0 for success non-zero for failure
2634 */
2635static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302636hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302637{
2638 int ret;
2639
2640 /*
2641 * both versions start with "REASSOC"
2642 * v1 has a bssid and channel # as an ASCII string
2643 * REASSOC xx:xx:xx:xx:xx:xx CH
2644 * v2 has a C struct
2645 * REASSOC <binary c struct>
2646 *
2647 * The first field in the v2 struct is also the bssid in ASCII.
2648 * But in the case of a v2 message the BSSID is NUL-terminated.
2649 * Hence we can peek at that offset to see if this is V1 or V2
2650 * REASSOC xx:xx:xx:xx:xx:xx*
2651 * 1111111111222222
2652 * 01234567890123456789012345
2653 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302654
2655 if (total_len < 26) {
2656 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2657 return -EINVAL;
2658 }
2659
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302660 if (command[25])
2661 ret = hdd_parse_reassoc_v1(pAdapter, command);
2662 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302663 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302664
2665 return ret;
2666}
2667#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2668
c_hpothu92367912014-05-01 15:18:17 +05302669static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2670{
c_hpothu39eb1e32014-06-26 16:31:50 +05302671 bcnMissRateContext_t *pCBCtx;
2672
2673 if (NULL == data)
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2676 return;
2677 }
c_hpothu92367912014-05-01 15:18:17 +05302678
2679 /* there is a race condition that exists between this callback
2680 function and the caller since the caller could time out either
2681 before or while this code is executing. we use a spinlock to
2682 serialize these actions */
2683 spin_lock(&hdd_context_lock);
2684
c_hpothu39eb1e32014-06-26 16:31:50 +05302685 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302686 gbcnMissRate = -1;
2687
c_hpothu39eb1e32014-06-26 16:31:50 +05302688 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302689 {
2690 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302691 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302692 spin_unlock(&hdd_context_lock);
2693 return ;
2694 }
2695
2696 if (VOS_STATUS_SUCCESS == status)
2697 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302698 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302699 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302700 else
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2703 }
2704
c_hpothu92367912014-05-01 15:18:17 +05302705 complete(&(pCBCtx->completion));
2706 spin_unlock(&hdd_context_lock);
2707
2708 return;
2709}
2710
Abhishek Singh08aa7762014-12-16 13:59:03 +05302711void hdd_FWStatisCB( VOS_STATUS status,
2712 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302713{
2714 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302715 hdd_adapter_t *pAdapter;
2716
2717 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2718
Abhishek Singh08aa7762014-12-16 13:59:03 +05302719 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302720 {
2721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2722 return;
2723 }
2724 /* there is a race condition that exists between this callback
2725 function and the caller since the caller could time out either
2726 before or while this code is executing. we use a spinlock to
2727 serialize these actions */
2728 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302729 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302730 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2731 {
2732 hddLog(VOS_TRACE_LEVEL_ERROR,
2733 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2734 spin_unlock(&hdd_context_lock);
2735 return;
2736 }
2737 pAdapter = fwStatsCtx->pAdapter;
2738 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2739 {
2740 hddLog(VOS_TRACE_LEVEL_ERROR,
2741 FL("pAdapter returned is NULL or invalid"));
2742 spin_unlock(&hdd_context_lock);
2743 return;
2744 }
2745 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302746 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302747 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302748 switch( fwStatsResult->type )
2749 {
2750 case FW_UBSP_STATS:
2751 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302752 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302753 hddLog(VOS_TRACE_LEVEL_INFO,
2754 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302755 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2756 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302757 }
2758 break;
2759 default:
2760 {
2761 hddLog(VOS_TRACE_LEVEL_ERROR,
2762 FL(" No handling for stats type %d"),fwStatsResult->type);
2763 }
2764 }
2765 }
2766 complete(&(fwStatsCtx->completion));
2767 spin_unlock(&hdd_context_lock);
2768 return;
2769}
2770
jge35567202017-06-21 16:39:38 +08002771/*
2772 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2773 *@pValue Pointer to MAXTXPOWER command
2774 *@pTxPower Pointer to tx power
2775 *
2776 *This function parses the MAXTXPOWER command passed in the format
2777 * MAXTXPOWER<space>X(Tx power in dbm)
2778 * For example input commands:
2779 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2780 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2781 *
2782 *return - 0 for success non-zero for failure
2783 */
2784static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2785{
2786 unsigned char *inPtr = pValue;
2787 int tempInt;
2788 int v = 0;
2789 *pTxPower = 0;
2790
2791 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2792 /* no argument after the command */
2793 if (NULL == inPtr)
2794 return -EINVAL;
2795 /* no space after the command */
2796 else if (SPACE_ASCII_VALUE != *inPtr)
2797 return -EINVAL;
2798
2799 /* removing empty spaces */
2800 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2801
2802 /* no argument followed by spaces */
2803 if ('\0' == *inPtr)
2804 return 0;
2805
2806 v = kstrtos32(inPtr, 10, &tempInt);
2807
2808 /* Range checking for passed parameter */
2809 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2810 return -EINVAL;
2811
2812 *pTxPower = tempInt;
2813
2814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2815 "SETMAXTXPOWER: %d", *pTxPower);
2816
2817 return 0;
2818}
2819
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302820static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2821{
2822 int ret = 0;
2823
2824 if (!pCfg || !command || !extra || !len)
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2827 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2828 ret = -EINVAL;
2829 return ret;
2830 }
2831
2832 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2833 {
2834 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2835 (int)pCfg->nActiveMaxChnTime);
2836 return ret;
2837 }
2838 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2839 {
2840 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2841 (int)pCfg->nActiveMinChnTime);
2842 return ret;
2843 }
2844 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2845 {
2846 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2847 (int)pCfg->nPassiveMaxChnTime);
2848 return ret;
2849 }
2850 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2851 {
2852 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2853 (int)pCfg->nPassiveMinChnTime);
2854 return ret;
2855 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302856 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2857 {
2858 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2859 (int)pCfg->nActiveMaxChnTime);
2860 return ret;
2861 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302862 else
2863 {
2864 ret = -EINVAL;
2865 }
2866
2867 return ret;
2868}
2869
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302870int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2871{
2872 if (command[len] != ' ')
2873 return -EINVAL;
2874
2875 return 0;
2876}
2877
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302878static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2879{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302880 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302881 hdd_config_t *pCfg;
2882 tANI_U8 *value = command;
2883 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302884 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302885
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302886 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2887 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302888 {
2889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2890 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2891 ret = -EINVAL;
2892 return ret;
2893 }
2894
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302895 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2896 sme_GetConfigParam(hHal, &smeConfig);
2897
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302898 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2899 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302900 if (hdd_drv_cmd_validate(command, 23))
2901 return -EINVAL;
2902
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302903 value = value + 24;
2904 temp = kstrtou32(value, 10, &val);
2905 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2906 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2907 {
2908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2909 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2910 ret = -EFAULT;
2911 return ret;
2912 }
2913 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302914 smeConfig.csrConfig.nActiveMaxChnTime = val;
2915 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302916 }
2917 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2918 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302919 if (hdd_drv_cmd_validate(command, 23))
2920 return -EINVAL;
2921
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302922 value = value + 24;
2923 temp = kstrtou32(value, 10, &val);
2924 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2925 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2926 {
2927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2928 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2929 ret = -EFAULT;
2930 return ret;
2931 }
2932 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302933 smeConfig.csrConfig.nActiveMinChnTime = val;
2934 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302935 }
2936 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2937 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302938 if (hdd_drv_cmd_validate(command, 24))
2939 return -EINVAL;
2940
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302941 value = value + 25;
2942 temp = kstrtou32(value, 10, &val);
2943 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2944 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2945 {
2946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2947 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2948 ret = -EFAULT;
2949 return ret;
2950 }
2951 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302952 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2953 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302954 }
2955 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2956 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302957 if (hdd_drv_cmd_validate(command, 24))
2958 return -EINVAL;
2959
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302960 value = value + 25;
2961 temp = kstrtou32(value, 10, &val);
2962 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2963 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2964 {
2965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2966 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2967 ret = -EFAULT;
2968 return ret;
2969 }
2970 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302971 smeConfig.csrConfig.nPassiveMinChnTime = val;
2972 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302973 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302974 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2975 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302976 if (hdd_drv_cmd_validate(command, 12))
2977 return -EINVAL;
2978
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302979 value = value + 13;
2980 temp = kstrtou32(value, 10, &val);
2981 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2982 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2983 {
2984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2985 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2986 ret = -EFAULT;
2987 return ret;
2988 }
2989 pCfg->nActiveMaxChnTime = val;
2990 smeConfig.csrConfig.nActiveMaxChnTime = val;
2991 sme_UpdateConfig(hHal, &smeConfig);
2992 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302993 else
2994 {
2995 ret = -EINVAL;
2996 }
2997
2998 return ret;
2999}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303000static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3001 tANI_U8 cmd_len)
3002{
3003 tANI_U8 *value;
3004 tANI_U8 fcc_constraint;
3005
3006 eHalStatus status;
3007 int ret = 0;
3008 value = cmd + cmd_len + 1;
3009
3010 ret = kstrtou8(value, 10, &fcc_constraint);
3011 if ((ret < 0) || (fcc_constraint > 1)) {
3012 /*
3013 * If the input value is greater than max value of datatype,
3014 * then also it is a failure
3015 */
3016 hddLog(VOS_TRACE_LEVEL_ERROR,
3017 "%s: value out of range", __func__);
3018 return -EINVAL;
3019 }
3020
Agrawal Ashish842eea82016-02-04 17:56:16 +05303021 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3022 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303023 if (status != eHAL_STATUS_SUCCESS)
3024 ret = -EPERM;
3025
3026 return ret;
3027}
3028
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303029/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303030
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303031 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3032 FW will send *ONE* CA ind to Host(even though it is duplicate).
3033 When Host send IOCTL (disable), FW doesn't perform any action.
3034 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3035 sends CA ind to host. (regard less of IOCTL status)
3036 \param - pHddCtx - HDD context
3037 \param - command - command received from framework
3038 \param - cmd_len - len of the command
3039
3040 \return - 0 on success, appropriate error values on failure.
3041
3042 --------------------------------------------------------------------------*/
3043int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3044{
3045 tANI_U8 set_value;
3046 int ret = 0;
3047 eHalStatus status;
3048
3049 ret = wlan_hdd_validate_context(pHddCtx);
3050 if (0 != ret)
3051 {
3052 ret = -EINVAL;
3053 goto exit;
3054 }
3055
3056 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3057 {
3058 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3059 " ini param to control channel avooidance indication");
3060 ret = 0;
3061 goto exit;
3062 }
3063
3064 set_value = command[cmd_len + 1] - '0';
3065 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3066 if (status != eHAL_STATUS_SUCCESS)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3069 " enableDisableChanAoidance command to SME\n", __func__);
3070 ret = -EINVAL;
3071 }
3072
3073exit:
3074 return ret;
3075}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303076
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303077/**
3078 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3079 * @pHddCtx: Pointer to the HDD context
3080 * @channel: channel to reassociate
3081 * @targetApBssid: Target AP/BSSID to reassociate
3082 *
3083 * Return: None
3084 */
3085#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3086static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3087 uint8_t channel, tSirMacAddr targetApBssid)
3088{
3089 tCsrHandoffRequest handoffInfo;
3090 handoffInfo.channel = channel;
3091 handoffInfo.src = FASTREASSOC;
3092 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3093 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3094}
3095#else
3096static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3097 uint8_t channel, tSirMacAddr targetApBssid)
3098{
3099}
3100#endif
3101
3102/**
3103 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3104 * @pAdapter: Pointer to HDD adapter
3105 * @channel: Channel to scan/roam
3106 * @targetApBssid: BSSID to roam
3107 *
3108 * Return: None
3109 */
3110#ifdef QCA_WIFI_ISOC
3111static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3112 uint8_t channel, tSirMacAddr targetApBssid)
3113{
3114 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3115 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3116}
3117#else
3118static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3119 uint8_t channel, tSirMacAddr targetApBssid)
3120{
3121}
3122#endif
3123
3124/**
3125 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3126 * @pAdapter: pointer to hdd adapter
3127 * @command: pointer to the command received
3128 *
3129 * Return: VOS_STATUS enum
3130 */
3131static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3132 uint8_t *command)
3133{
3134 tANI_U8 *value = command;
3135 tANI_U8 channel = 0;
3136 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303137 hdd_station_ctx_t *pHddStaCtx = NULL;
3138 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303139 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303140 tCsrRoamModifyProfileFields mod_profile_fields;
3141 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303142 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3144
3145 /* if not associated, no need to proceed with reassoc */
3146 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3147 hddLog(LOG1, FL("Not associated!"));
3148 return eHAL_STATUS_FAILURE;
3149 }
3150
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303151 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3152 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303153 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3154 return eHAL_STATUS_FAILURE;
3155 }
3156
3157 /* if the target bssid is same as currently associated AP,
3158 then no need to proceed with reassoc */
3159 if (vos_mem_compare(targetApBssid,
3160 pHddStaCtx->conn_info.bssId,
3161 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303162 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3163 &mod_profile_fields);
3164 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3165 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303166 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303167 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303168 }
3169
3170 /* Check channel number is a valid channel number */
3171 if (VOS_STATUS_SUCCESS !=
3172 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3173 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3174 return eHAL_STATUS_FAILURE;
3175 }
3176
3177 /* Proceed with reassoc */
3178 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3179
3180 /* Proceed with scan/roam */
3181 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3182
3183 return eHAL_STATUS_SUCCESS;
3184}
3185
3186/**
3187 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3188 * @handoffInfo: Pointer to the csr Handoff Request.
3189 *
3190 * Return: None
3191 */
3192#ifndef QCA_WIFI_ISOC
3193static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3194{
3195 handoffInfo->src = REASSOC;
3196}
3197#else
3198static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3199{
3200}
3201#endif
3202
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003203static int hdd_driver_command(hdd_adapter_t *pAdapter,
3204 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003205{
Jeff Johnson295189b2012-06-20 16:38:30 -07003206 hdd_priv_data_t priv_data;
3207 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303208 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3209 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003210 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303211 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303212#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3213 struct cfg80211_mgmt_tx_params params;
3214#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303215
3216 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003217 /*
3218 * Note that valid pointers are provided by caller
3219 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003220
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003221 /* copy to local struct to avoid numerous changes to legacy code */
3222 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003223
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003224 if (priv_data.total_len <= 0 ||
3225 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003226 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003227 hddLog(VOS_TRACE_LEVEL_WARN,
3228 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3229 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003230 ret = -EINVAL;
3231 goto exit;
3232 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303233 status = wlan_hdd_validate_context(pHddCtx);
3234 if (0 != status)
3235 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303236 ret = -EINVAL;
3237 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303238 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003239 /* Allocate +1 for '\0' */
3240 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003241 if (!command)
3242 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003243 hddLog(VOS_TRACE_LEVEL_ERROR,
3244 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003245 ret = -ENOMEM;
3246 goto exit;
3247 }
3248
3249 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3250 {
3251 ret = -EFAULT;
3252 goto exit;
3253 }
3254
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003255 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003256 command[priv_data.total_len] = '\0';
3257
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003258 /* at one time the following block of code was conditional. braces
3259 * have been retained to avoid re-indenting the legacy code
3260 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003261 {
3262 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3263
3264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003265 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003266
3267 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3268 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303269 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3270 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3271 pAdapter->sessionId, (unsigned)
3272 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3273 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3274 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3275 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003276 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3277 sizeof(tSirMacAddr)))
3278 {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003280 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003281 ret = -EFAULT;
3282 }
3283 }
Amar Singhal0974e402013-02-12 14:27:46 -08003284 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003285 {
Amar Singhal0974e402013-02-12 14:27:46 -08003286 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003287
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303288 ret = hdd_drv_cmd_validate(command, 7);
3289 if (ret)
3290 goto exit;
3291
Jeff Johnson295189b2012-06-20 16:38:30 -07003292 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003293
3294 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003295 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003297 "%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 +05303298 if(VOS_FTM_MODE != hdd_get_conparam())
3299 {
3300 /* Change band request received */
3301 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3302 if(ret < 0)
3303 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3304 "%s: failed to set band ret=%d", __func__, ret);
3305 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003306 }
Kiet Lamf040f472013-11-20 21:15:23 +05303307 else if(strncmp(command, "SETWMMPS", 8) == 0)
3308 {
3309 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303310
3311 ret = hdd_drv_cmd_validate(command, 8);
3312 if (ret)
3313 goto exit;
3314
Kiet Lamf040f472013-11-20 21:15:23 +05303315 ret = hdd_wmmps_helper(pAdapter, ptr);
3316 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303317
3318 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3319 {
3320 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303321
3322 ret = hdd_drv_cmd_validate(command, 8);
3323 if (ret)
3324 goto exit;
3325
Agarwal Ashishef54a182014-12-16 15:07:31 +05303326 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3327 }
3328
Jeff Johnson32d95a32012-09-10 13:15:23 -07003329 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3330 {
3331 char *country_code;
3332
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 ret = hdd_drv_cmd_validate(command, 7);
3334 if (ret)
3335 goto exit;
3336
Jeff Johnson32d95a32012-09-10 13:15:23 -07003337 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003338
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003339 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003340 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003341#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303342 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003343#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003344 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3345 (void *)(tSmeChangeCountryCallback)
3346 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303347 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003348 if (eHAL_STATUS_SUCCESS == ret)
3349 {
3350 ret = wait_for_completion_interruptible_timeout(
3351 &pAdapter->change_country_code,
3352 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3353 if (0 >= ret)
3354 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303356 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003357 }
3358 }
3359 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003360 {
3361 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003362 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003363 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003364 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003365
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003366 }
3367 /*
3368 command should be a string having format
3369 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3370 */
Amar Singhal0974e402013-02-12 14:27:46 -08003371 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003372 {
Amar Singhal0974e402013-02-12 14:27:46 -08003373 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003374
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003376 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003377
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003378 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003379 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003380 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3381 {
3382 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303383 tANI_U8 *ptr;
3384
3385 ret = hdd_drv_cmd_validate(command, 14);
3386 if (ret)
3387 goto exit;
3388
3389 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003390
3391 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3393 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3394 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003395 hdd_set_wlan_suspend_mode(suspend);
3396 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003397#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3398 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3399 {
3400 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003401 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003402 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3403 eHalStatus status = eHAL_STATUS_SUCCESS;
3404
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303405 ret = hdd_drv_cmd_validate(command, 14);
3406 if (ret)
3407 goto exit;
3408
Srinivas Girigowdade697412013-02-14 16:31:48 -08003409 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3410 value = value + 15;
3411
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003412 /* Convert the value from ascii to integer */
3413 ret = kstrtos8(value, 10, &rssi);
3414 if (ret < 0)
3415 {
3416 /* If the input value is greater than max value of datatype, then also
3417 kstrtou8 fails */
3418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3419 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003420 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003421 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3422 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3423 ret = -EINVAL;
3424 goto exit;
3425 }
3426
Srinivas Girigowdade697412013-02-14 16:31:48 -08003427 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003428
Srinivas Girigowdade697412013-02-14 16:31:48 -08003429 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3430 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3431 {
3432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3433 "Neighbor lookup threshold value %d is out of range"
3434 " (Min: %d Max: %d)", lookUpThreshold,
3435 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3436 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3437 ret = -EINVAL;
3438 goto exit;
3439 }
3440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3442 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3443 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3445 "%s: Received Command to Set Roam trigger"
3446 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3447
3448 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3449 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3450 if (eHAL_STATUS_SUCCESS != status)
3451 {
3452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3453 "%s: Failed to set roam trigger, try again", __func__);
3454 ret = -EPERM;
3455 goto exit;
3456 }
3457
3458 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303459 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003460 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3461 }
3462 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3463 {
3464 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3465 int rssi = (-1) * lookUpThreshold;
3466 char extra[32];
3467 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303468 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3469 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3470 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003471 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303472 len = VOS_MIN(priv_data.total_len, len + 1);
3473 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003474 {
3475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3476 "%s: failed to copy data to user buffer", __func__);
3477 ret = -EFAULT;
3478 goto exit;
3479 }
3480 }
3481 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3482 {
3483 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003484 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003485 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003486
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303487 ret = hdd_drv_cmd_validate(command, 17);
3488 if (ret)
3489 goto exit;
3490
Srinivas Girigowdade697412013-02-14 16:31:48 -08003491 /* input refresh period is in terms of seconds */
3492 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3493 value = value + 18;
3494 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003495 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003496 if (ret < 0)
3497 {
3498 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003499 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003501 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003502 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3504 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003505 ret = -EINVAL;
3506 goto exit;
3507 }
3508
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003509 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3510 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003511 {
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003513 "Roam scan period value %d is out of range"
3514 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003515 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3516 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003517 ret = -EINVAL;
3518 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303519 }
3520 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3521 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3522 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003523 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003524
3525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3526 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003527 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003528
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003529 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3530 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003531 }
3532 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3533 {
3534 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3535 char extra[32];
3536 tANI_U8 len = 0;
3537
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303538 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3539 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3540 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003541 len = scnprintf(extra, sizeof(extra), "%s %d",
3542 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003543 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303544 len = VOS_MIN(priv_data.total_len, len + 1);
3545 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3547 "%s: failed to copy data to user buffer", __func__);
3548 ret = -EFAULT;
3549 goto exit;
3550 }
3551 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003552 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3553 {
3554 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003555 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003556 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003557
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303558 ret = hdd_drv_cmd_validate(command, 24);
3559 if (ret)
3560 goto exit;
3561
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003562 /* input refresh period is in terms of seconds */
3563 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3564 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003565
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003566 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003567 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003568 if (ret < 0)
3569 {
3570 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003571 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003573 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003574 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003575 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3576 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3577 ret = -EINVAL;
3578 goto exit;
3579 }
3580
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003581 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3582 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3583 {
3584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3585 "Neighbor scan results refresh period value %d is out of range"
3586 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3587 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3588 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3589 ret = -EINVAL;
3590 goto exit;
3591 }
3592 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3593
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3595 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003596 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003597
3598 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3599 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3600 }
3601 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3602 {
3603 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3604 char extra[32];
3605 tANI_U8 len = 0;
3606
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003607 len = scnprintf(extra, sizeof(extra), "%s %d",
3608 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003609 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303610 len = VOS_MIN(priv_data.total_len, len + 1);
3611 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3613 "%s: failed to copy data to user buffer", __func__);
3614 ret = -EFAULT;
3615 goto exit;
3616 }
3617 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003618#ifdef FEATURE_WLAN_LFR
3619 /* SETROAMMODE */
3620 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3621 {
3622 tANI_U8 *value = command;
3623 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3624
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303625 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
3626 if (ret)
3627 goto exit;
3628
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003629 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3630 value = value + SIZE_OF_SETROAMMODE + 1;
3631
3632 /* Convert the value from ascii to integer */
3633 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3634 if (ret < 0)
3635 {
3636 /* If the input value is greater than max value of datatype, then also
3637 kstrtou8 fails */
3638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3639 "%s: kstrtou8 failed range [%d - %d]", __func__,
3640 CFG_LFR_FEATURE_ENABLED_MIN,
3641 CFG_LFR_FEATURE_ENABLED_MAX);
3642 ret = -EINVAL;
3643 goto exit;
3644 }
3645 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3646 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3647 {
3648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "Roam Mode value %d is out of range"
3650 " (Min: %d Max: %d)", roamMode,
3651 CFG_LFR_FEATURE_ENABLED_MIN,
3652 CFG_LFR_FEATURE_ENABLED_MAX);
3653 ret = -EINVAL;
3654 goto exit;
3655 }
3656
3657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3658 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3659 /*
3660 * Note that
3661 * SETROAMMODE 0 is to enable LFR while
3662 * SETROAMMODE 1 is to disable LFR, but
3663 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3664 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3665 */
3666 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3667 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3668 else
3669 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3670
3671 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3672 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3673 }
3674 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303675 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003676 {
3677 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3678 char extra[32];
3679 tANI_U8 len = 0;
3680
3681 /*
3682 * roamMode value shall be inverted because the sementics is different.
3683 */
3684 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3685 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3686 else
3687 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3688
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003689 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303690 len = VOS_MIN(priv_data.total_len, len + 1);
3691 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3693 "%s: failed to copy data to user buffer", __func__);
3694 ret = -EFAULT;
3695 goto exit;
3696 }
3697 }
3698#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003699#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003700#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003701 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3702 {
3703 tANI_U8 *value = command;
3704 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3705
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303706 ret = hdd_drv_cmd_validate(command, 12);
3707 if (ret)
3708 goto exit;
3709
Srinivas Girigowdade697412013-02-14 16:31:48 -08003710 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3711 value = value + 13;
3712 /* Convert the value from ascii to integer */
3713 ret = kstrtou8(value, 10, &roamRssiDiff);
3714 if (ret < 0)
3715 {
3716 /* If the input value is greater than max value of datatype, then also
3717 kstrtou8 fails */
3718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3719 "%s: kstrtou8 failed range [%d - %d]", __func__,
3720 CFG_ROAM_RSSI_DIFF_MIN,
3721 CFG_ROAM_RSSI_DIFF_MAX);
3722 ret = -EINVAL;
3723 goto exit;
3724 }
3725
3726 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3727 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3728 {
3729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3730 "Roam rssi diff value %d is out of range"
3731 " (Min: %d Max: %d)", roamRssiDiff,
3732 CFG_ROAM_RSSI_DIFF_MIN,
3733 CFG_ROAM_RSSI_DIFF_MAX);
3734 ret = -EINVAL;
3735 goto exit;
3736 }
3737
3738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3739 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3740
3741 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3742 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3743 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303744 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003745 {
3746 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3747 char extra[32];
3748 tANI_U8 len = 0;
3749
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303750 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3751 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3752 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003753 len = scnprintf(extra, sizeof(extra), "%s %d",
3754 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303755 len = VOS_MIN(priv_data.total_len, len + 1);
3756 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3758 "%s: failed to copy data to user buffer", __func__);
3759 ret = -EFAULT;
3760 goto exit;
3761 }
3762 }
3763#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003764#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003765 else if (strncmp(command, "GETBAND", 7) == 0)
3766 {
3767 int band = -1;
3768 char extra[32];
3769 tANI_U8 len = 0;
3770 hdd_getBand_helper(pHddCtx, &band);
3771
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303772 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3773 TRACE_CODE_HDD_GETBAND_IOCTL,
3774 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003775 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303776 len = VOS_MIN(priv_data.total_len, len + 1);
3777 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3779 "%s: failed to copy data to user buffer", __func__);
3780 ret = -EFAULT;
3781 goto exit;
3782 }
3783 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003784 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3785 {
3786 tANI_U8 *value = command;
3787 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3788 tANI_U8 numChannels = 0;
3789 eHalStatus status = eHAL_STATUS_SUCCESS;
3790
3791 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3792 if (eHAL_STATUS_SUCCESS != status)
3793 {
3794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3795 "%s: Failed to parse channel list information", __func__);
3796 ret = -EINVAL;
3797 goto exit;
3798 }
3799
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303800 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3801 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3802 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003803 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3804 {
3805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3806 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3807 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3808 ret = -EINVAL;
3809 goto exit;
3810 }
3811 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3812 numChannels);
3813 if (eHAL_STATUS_SUCCESS != status)
3814 {
3815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3816 "%s: Failed to update channel list information", __func__);
3817 ret = -EINVAL;
3818 goto exit;
3819 }
3820 }
3821 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3822 {
3823 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3824 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003825 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003826 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003827 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003828
3829 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3830 ChannelList, &numChannels ))
3831 {
3832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3833 "%s: failed to get roam scan channel list", __func__);
3834 ret = -EFAULT;
3835 goto exit;
3836 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303837 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3838 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3839 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003840 /* output channel list is of the format
3841 [Number of roam scan channels][Channel1][Channel2]... */
3842 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003843 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303844 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003845 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003846 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3847 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003848 }
3849
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303850 len = VOS_MIN(priv_data.total_len, len + 1);
3851 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: failed to copy data to user buffer", __func__);
3855 ret = -EFAULT;
3856 goto exit;
3857 }
3858 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003859 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3860 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003861 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003862 char extra[32];
3863 tANI_U8 len = 0;
3864
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003865 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003866 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003867 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003868 hdd_is_okc_mode_enabled(pHddCtx) &&
3869 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3870 {
3871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003872 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003873 " hence this operation is not permitted!", __func__);
3874 ret = -EPERM;
3875 goto exit;
3876 }
3877
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003878 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003879 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303880 len = VOS_MIN(priv_data.total_len, len + 1);
3881 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003882 {
3883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3884 "%s: failed to copy data to user buffer", __func__);
3885 ret = -EFAULT;
3886 goto exit;
3887 }
3888 }
3889 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3890 {
3891 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3892 char extra[32];
3893 tANI_U8 len = 0;
3894
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003895 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003896 then this operation is not permitted (return FAILURE) */
3897 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003898 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003899 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3900 {
3901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003902 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003903 " hence this operation is not permitted!", __func__);
3904 ret = -EPERM;
3905 goto exit;
3906 }
3907
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003908 len = scnprintf(extra, sizeof(extra), "%s %d",
3909 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303910 len = VOS_MIN(priv_data.total_len, len + 1);
3911 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003912 {
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 "%s: failed to copy data to user buffer", __func__);
3915 ret = -EFAULT;
3916 goto exit;
3917 }
3918 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003919 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003920 {
3921 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3922 char extra[32];
3923 tANI_U8 len = 0;
3924
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003925 len = scnprintf(extra, sizeof(extra), "%s %d",
3926 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303927 len = VOS_MIN(priv_data.total_len, len + 1);
3928 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003929 {
3930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3931 "%s: failed to copy data to user buffer", __func__);
3932 ret = -EFAULT;
3933 goto exit;
3934 }
3935 }
3936 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3937 {
3938 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3939 char extra[32];
3940 tANI_U8 len = 0;
3941
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003942 len = scnprintf(extra, sizeof(extra), "%s %d",
3943 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303944 len = VOS_MIN(priv_data.total_len, len + 1);
3945 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003946 {
3947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3948 "%s: failed to copy data to user buffer", __func__);
3949 ret = -EFAULT;
3950 goto exit;
3951 }
3952 }
3953 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3954 {
3955 tANI_U8 *value = command;
3956 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3957
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303958 ret = hdd_drv_cmd_validate(command, 25);
3959 if (ret)
3960 goto exit;
3961
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003962 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3963 value = value + 26;
3964 /* Convert the value from ascii to integer */
3965 ret = kstrtou8(value, 10, &minTime);
3966 if (ret < 0)
3967 {
3968 /* If the input value is greater than max value of datatype, then also
3969 kstrtou8 fails */
3970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3971 "%s: kstrtou8 failed range [%d - %d]", __func__,
3972 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3973 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3974 ret = -EINVAL;
3975 goto exit;
3976 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003977 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3978 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3979 {
3980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3981 "scan min channel time value %d is out of range"
3982 " (Min: %d Max: %d)", minTime,
3983 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3984 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3985 ret = -EINVAL;
3986 goto exit;
3987 }
3988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3990 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3991 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3993 "%s: Received Command to change channel min time = %d", __func__, minTime);
3994
3995 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3996 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3997 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003998 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3999 {
4000 tANI_U8 *value = command;
4001 tANI_U8 channel = 0;
4002 tANI_U8 dwellTime = 0;
4003 tANI_U8 bufLen = 0;
4004 tANI_U8 *buf = NULL;
4005 tSirMacAddr targetApBssid;
4006 eHalStatus status = eHAL_STATUS_SUCCESS;
4007 struct ieee80211_channel chan;
4008 tANI_U8 finalLen = 0;
4009 tANI_U8 *finalBuf = NULL;
4010 tANI_U8 temp = 0;
4011 u64 cookie;
4012 hdd_station_ctx_t *pHddStaCtx = NULL;
4013 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4014
4015 /* if not associated, no need to send action frame */
4016 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4017 {
4018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4019 ret = -EINVAL;
4020 goto exit;
4021 }
4022
4023 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4024 &dwellTime, &buf, &bufLen);
4025 if (eHAL_STATUS_SUCCESS != status)
4026 {
4027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4028 "%s: Failed to parse send action frame data", __func__);
4029 ret = -EINVAL;
4030 goto exit;
4031 }
4032
4033 /* if the target bssid is different from currently associated AP,
4034 then no need to send action frame */
4035 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4036 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4037 {
4038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4039 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004040 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004041 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004042 goto exit;
4043 }
4044
4045 /* if the channel number is different from operating channel then
4046 no need to send action frame */
4047 if (channel != pHddStaCtx->conn_info.operationChannel)
4048 {
4049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4050 "%s: channel(%d) is different from operating channel(%d)",
4051 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4052 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004053 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004054 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004055 goto exit;
4056 }
4057 chan.center_freq = sme_ChnToFreq(channel);
4058
4059 finalLen = bufLen + 24;
4060 finalBuf = vos_mem_malloc(finalLen);
4061 if (NULL == finalBuf)
4062 {
4063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4064 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004065 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004066 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004067 goto exit;
4068 }
4069 vos_mem_zero(finalBuf, finalLen);
4070
4071 /* Fill subtype */
4072 temp = SIR_MAC_MGMT_ACTION << 4;
4073 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4074
4075 /* Fill type */
4076 temp = SIR_MAC_MGMT_FRAME;
4077 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4078
4079 /* Fill destination address (bssid of the AP) */
4080 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4081
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004082 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004083 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4084
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004085 /* Fill BSSID (AP mac address) */
4086 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004087
4088 /* Fill received buffer from 24th address */
4089 vos_mem_copy(finalBuf + 24, buf, bufLen);
4090
Jeff Johnson11c33152013-04-16 17:52:40 -07004091 /* done with the parsed buffer */
4092 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004093 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004094
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4096 params.chan = &chan;
4097 params.offchan = 0;
4098 params.wait = dwellTime;
4099 params.buf = finalBuf;
4100 params.len = finalLen;
4101 params.no_cck = 1;
4102 params.dont_wait_for_ack = 1;
4103 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4104#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304105 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4107 &(pAdapter->wdev),
4108#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004109 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004110#endif
4111 &chan, 0,
4112#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4113 NL80211_CHAN_HT20, 1,
4114#endif
4115 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004116 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304117#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004118 vos_mem_free(finalBuf);
4119 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004120 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4121 {
4122 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4123 char extra[32];
4124 tANI_U8 len = 0;
4125
4126 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004127 len = scnprintf(extra, sizeof(extra), "%s %d",
4128 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304129 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4130 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4131 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304132 len = VOS_MIN(priv_data.total_len, len + 1);
4133 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004134 {
4135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4136 "%s: failed to copy data to user buffer", __func__);
4137 ret = -EFAULT;
4138 goto exit;
4139 }
4140 }
4141 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4142 {
4143 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004144 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004145
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304146 ret = hdd_drv_cmd_validate(command, 18);
4147 if (ret)
4148 goto exit;
4149
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4151 value = value + 19;
4152 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004153 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004154 if (ret < 0)
4155 {
4156 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004157 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004159 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004160 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4161 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4162 ret = -EINVAL;
4163 goto exit;
4164 }
4165
4166 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4167 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4168 {
4169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4170 "lfr mode value %d is out of range"
4171 " (Min: %d Max: %d)", maxTime,
4172 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4173 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4174 ret = -EINVAL;
4175 goto exit;
4176 }
4177
4178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4179 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4180
4181 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4182 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4183 }
4184 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4185 {
4186 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4187 char extra[32];
4188 tANI_U8 len = 0;
4189
4190 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004191 len = scnprintf(extra, sizeof(extra), "%s %d",
4192 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304193 len = VOS_MIN(priv_data.total_len, len + 1);
4194 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004195 {
4196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4197 "%s: failed to copy data to user buffer", __func__);
4198 ret = -EFAULT;
4199 goto exit;
4200 }
4201 }
4202 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4203 {
4204 tANI_U8 *value = command;
4205 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4206
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304207 ret = hdd_drv_cmd_validate(command, 15);
4208 if (ret)
4209 goto exit;
4210
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004211 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4212 value = value + 16;
4213 /* Convert the value from ascii to integer */
4214 ret = kstrtou16(value, 10, &val);
4215 if (ret < 0)
4216 {
4217 /* If the input value is greater than max value of datatype, then also
4218 kstrtou16 fails */
4219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4220 "%s: kstrtou16 failed range [%d - %d]", __func__,
4221 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4222 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4223 ret = -EINVAL;
4224 goto exit;
4225 }
4226
4227 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4228 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4229 {
4230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4231 "scan home time value %d is out of range"
4232 " (Min: %d Max: %d)", val,
4233 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4234 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4235 ret = -EINVAL;
4236 goto exit;
4237 }
4238
4239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4240 "%s: Received Command to change scan home time = %d", __func__, val);
4241
4242 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4243 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4244 }
4245 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4246 {
4247 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4248 char extra[32];
4249 tANI_U8 len = 0;
4250
4251 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004252 len = scnprintf(extra, sizeof(extra), "%s %d",
4253 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304254 len = VOS_MIN(priv_data.total_len, len + 1);
4255 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004256 {
4257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4258 "%s: failed to copy data to user buffer", __func__);
4259 ret = -EFAULT;
4260 goto exit;
4261 }
4262 }
4263 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4264 {
4265 tANI_U8 *value = command;
4266 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4267
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304268 ret = hdd_drv_cmd_validate(command, 16);
4269 if (ret)
4270 goto exit;
4271
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004272 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4273 value = value + 17;
4274 /* Convert the value from ascii to integer */
4275 ret = kstrtou8(value, 10, &val);
4276 if (ret < 0)
4277 {
4278 /* If the input value is greater than max value of datatype, then also
4279 kstrtou8 fails */
4280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4281 "%s: kstrtou8 failed range [%d - %d]", __func__,
4282 CFG_ROAM_INTRA_BAND_MIN,
4283 CFG_ROAM_INTRA_BAND_MAX);
4284 ret = -EINVAL;
4285 goto exit;
4286 }
4287
4288 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4289 (val > CFG_ROAM_INTRA_BAND_MAX))
4290 {
4291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4292 "intra band mode value %d is out of range"
4293 " (Min: %d Max: %d)", val,
4294 CFG_ROAM_INTRA_BAND_MIN,
4295 CFG_ROAM_INTRA_BAND_MAX);
4296 ret = -EINVAL;
4297 goto exit;
4298 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4300 "%s: Received Command to change intra band = %d", __func__, val);
4301
4302 pHddCtx->cfg_ini->nRoamIntraBand = val;
4303 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4304 }
4305 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4306 {
4307 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4308 char extra[32];
4309 tANI_U8 len = 0;
4310
4311 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004312 len = scnprintf(extra, sizeof(extra), "%s %d",
4313 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304314 len = VOS_MIN(priv_data.total_len, len + 1);
4315 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004316 {
4317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4318 "%s: failed to copy data to user buffer", __func__);
4319 ret = -EFAULT;
4320 goto exit;
4321 }
4322 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004323 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4324 {
4325 tANI_U8 *value = command;
4326 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4327
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304328 ret = hdd_drv_cmd_validate(command, 14);
4329 if (ret)
4330 goto exit;
4331
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004332 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4333 value = value + 15;
4334 /* Convert the value from ascii to integer */
4335 ret = kstrtou8(value, 10, &nProbes);
4336 if (ret < 0)
4337 {
4338 /* If the input value is greater than max value of datatype, then also
4339 kstrtou8 fails */
4340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4341 "%s: kstrtou8 failed range [%d - %d]", __func__,
4342 CFG_ROAM_SCAN_N_PROBES_MIN,
4343 CFG_ROAM_SCAN_N_PROBES_MAX);
4344 ret = -EINVAL;
4345 goto exit;
4346 }
4347
4348 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4349 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4350 {
4351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4352 "NProbes value %d is out of range"
4353 " (Min: %d Max: %d)", nProbes,
4354 CFG_ROAM_SCAN_N_PROBES_MIN,
4355 CFG_ROAM_SCAN_N_PROBES_MAX);
4356 ret = -EINVAL;
4357 goto exit;
4358 }
4359
4360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4361 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4362
4363 pHddCtx->cfg_ini->nProbes = nProbes;
4364 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4365 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304366 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004367 {
4368 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4369 char extra[32];
4370 tANI_U8 len = 0;
4371
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004372 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304373 len = VOS_MIN(priv_data.total_len, len + 1);
4374 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4376 "%s: failed to copy data to user buffer", __func__);
4377 ret = -EFAULT;
4378 goto exit;
4379 }
4380 }
4381 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4382 {
4383 tANI_U8 *value = command;
4384 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4385
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304386 ret = hdd_drv_cmd_validate(command, 19);
4387 if (ret)
4388 goto exit;
4389
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004390 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4391 /* input value is in units of msec */
4392 value = value + 20;
4393 /* Convert the value from ascii to integer */
4394 ret = kstrtou16(value, 10, &homeAwayTime);
4395 if (ret < 0)
4396 {
4397 /* If the input value is greater than max value of datatype, then also
4398 kstrtou8 fails */
4399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4400 "%s: kstrtou8 failed range [%d - %d]", __func__,
4401 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4402 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4403 ret = -EINVAL;
4404 goto exit;
4405 }
4406
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004407 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4408 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4409 {
4410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4411 "homeAwayTime value %d is out of range"
4412 " (Min: %d Max: %d)", homeAwayTime,
4413 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4414 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4415 ret = -EINVAL;
4416 goto exit;
4417 }
4418
4419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4420 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004421 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4422 {
4423 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4424 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4425 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004426 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304427 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004428 {
4429 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4430 char extra[32];
4431 tANI_U8 len = 0;
4432
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004433 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304434 len = VOS_MIN(priv_data.total_len, len + 1);
4435 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4437 "%s: failed to copy data to user buffer", __func__);
4438 ret = -EFAULT;
4439 goto exit;
4440 }
4441 }
4442 else if (strncmp(command, "REASSOC", 7) == 0)
4443 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304444 ret = hdd_drv_cmd_validate(command, 7);
4445 if (ret)
4446 goto exit;
4447
4448 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304449 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004450 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004451 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004452 else if (strncmp(command, "SETWESMODE", 10) == 0)
4453 {
4454 tANI_U8 *value = command;
4455 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4456
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304457 ret = hdd_drv_cmd_validate(command, 10);
4458 if (ret)
4459 goto exit;
4460
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004461 /* Move pointer to ahead of SETWESMODE<delimiter> */
4462 value = value + 11;
4463 /* Convert the value from ascii to integer */
4464 ret = kstrtou8(value, 10, &wesMode);
4465 if (ret < 0)
4466 {
4467 /* If the input value is greater than max value of datatype, then also
4468 kstrtou8 fails */
4469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4470 "%s: kstrtou8 failed range [%d - %d]", __func__,
4471 CFG_ENABLE_WES_MODE_NAME_MIN,
4472 CFG_ENABLE_WES_MODE_NAME_MAX);
4473 ret = -EINVAL;
4474 goto exit;
4475 }
4476
4477 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4478 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4479 {
4480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4481 "WES Mode value %d is out of range"
4482 " (Min: %d Max: %d)", wesMode,
4483 CFG_ENABLE_WES_MODE_NAME_MIN,
4484 CFG_ENABLE_WES_MODE_NAME_MAX);
4485 ret = -EINVAL;
4486 goto exit;
4487 }
4488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4489 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4490
4491 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4492 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4493 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304494 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004495 {
4496 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4497 char extra[32];
4498 tANI_U8 len = 0;
4499
Arif Hussain826d9412013-11-12 16:44:54 -08004500 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304501 len = VOS_MIN(priv_data.total_len, len + 1);
4502 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4504 "%s: failed to copy data to user buffer", __func__);
4505 ret = -EFAULT;
4506 goto exit;
4507 }
4508 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004509#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004510#ifdef FEATURE_WLAN_LFR
4511 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4512 {
4513 tANI_U8 *value = command;
4514 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4515
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304516 ret = hdd_drv_cmd_validate(command, 11);
4517 if (ret)
4518 goto exit;
4519
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004520 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4521 value = value + 12;
4522 /* Convert the value from ascii to integer */
4523 ret = kstrtou8(value, 10, &lfrMode);
4524 if (ret < 0)
4525 {
4526 /* If the input value is greater than max value of datatype, then also
4527 kstrtou8 fails */
4528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4529 "%s: kstrtou8 failed range [%d - %d]", __func__,
4530 CFG_LFR_FEATURE_ENABLED_MIN,
4531 CFG_LFR_FEATURE_ENABLED_MAX);
4532 ret = -EINVAL;
4533 goto exit;
4534 }
4535
4536 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4537 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4538 {
4539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4540 "lfr mode value %d is out of range"
4541 " (Min: %d Max: %d)", lfrMode,
4542 CFG_LFR_FEATURE_ENABLED_MIN,
4543 CFG_LFR_FEATURE_ENABLED_MAX);
4544 ret = -EINVAL;
4545 goto exit;
4546 }
4547
4548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4549 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4550
4551 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4552 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4553 }
4554#endif
4555#ifdef WLAN_FEATURE_VOWIFI_11R
4556 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4557 {
4558 tANI_U8 *value = command;
4559 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4560
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304561 ret = hdd_drv_cmd_validate(command, 17);
4562 if (ret)
4563 goto exit;
4564
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004565 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4566 value = value + 18;
4567 /* Convert the value from ascii to integer */
4568 ret = kstrtou8(value, 10, &ft);
4569 if (ret < 0)
4570 {
4571 /* If the input value is greater than max value of datatype, then also
4572 kstrtou8 fails */
4573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4574 "%s: kstrtou8 failed range [%d - %d]", __func__,
4575 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4576 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4577 ret = -EINVAL;
4578 goto exit;
4579 }
4580
4581 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4582 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4583 {
4584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4585 "ft mode value %d is out of range"
4586 " (Min: %d Max: %d)", ft,
4587 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4588 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4589 ret = -EINVAL;
4590 goto exit;
4591 }
4592
4593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4594 "%s: Received Command to change ft mode = %d", __func__, ft);
4595
4596 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4597 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4598 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304599 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4600 {
4601 tANI_U8 *value = command;
4602 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304603
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304604 ret = hdd_drv_cmd_validate(command, 14);
4605 if (ret)
4606 goto exit;
4607
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304608 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4609 value = value + 15;
4610 /* Convert the value from ascii to integer */
4611 ret = kstrtou8(value, 10, &dfsScanMode);
4612 if (ret < 0)
4613 {
4614 /* If the input value is greater than max value of
4615 datatype, then also kstrtou8 fails
4616 */
4617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4618 "%s: kstrtou8 failed range [%d - %d]", __func__,
4619 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4620 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4621 ret = -EINVAL;
4622 goto exit;
4623 }
4624
4625 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4626 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4627 {
4628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4629 "dfsScanMode value %d is out of range"
4630 " (Min: %d Max: %d)", dfsScanMode,
4631 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4632 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4633 ret = -EINVAL;
4634 goto exit;
4635 }
4636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4637 "%s: Received Command to Set DFS Scan Mode = %d",
4638 __func__, dfsScanMode);
4639
4640 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4641 }
4642 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4643 {
4644 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4645 char extra[32];
4646 tANI_U8 len = 0;
4647
4648 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304649 len = VOS_MIN(priv_data.total_len, len + 1);
4650 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304651 {
4652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4653 "%s: failed to copy data to user buffer", __func__);
4654 ret = -EFAULT;
4655 goto exit;
4656 }
4657 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304658 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4659 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304660 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4661 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304662 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304663 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004664#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004665#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004666 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4667 {
4668 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004669 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004670
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304671 ret = hdd_drv_cmd_validate(command, 10);
4672 if (ret)
4673 goto exit;
4674
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004675 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004676 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004677 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004678 hdd_is_okc_mode_enabled(pHddCtx) &&
4679 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4680 {
4681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004682 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004683 " hence this operation is not permitted!", __func__);
4684 ret = -EPERM;
4685 goto exit;
4686 }
4687
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004688 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4689 value = value + 11;
4690 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004691 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004692 if (ret < 0)
4693 {
4694 /* If the input value is greater than max value of datatype, then also
4695 kstrtou8 fails */
4696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4697 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004698 CFG_ESE_FEATURE_ENABLED_MIN,
4699 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004700 ret = -EINVAL;
4701 goto exit;
4702 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004703 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4704 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004705 {
4706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004707 "Ese mode value %d is out of range"
4708 " (Min: %d Max: %d)", eseMode,
4709 CFG_ESE_FEATURE_ENABLED_MIN,
4710 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004711 ret = -EINVAL;
4712 goto exit;
4713 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004716
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004717 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4718 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004719 }
4720#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004721 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4722 {
4723 tANI_U8 *value = command;
4724 tANI_BOOLEAN roamScanControl = 0;
4725
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304726 ret = hdd_drv_cmd_validate(command, 18);
4727 if (ret)
4728 goto exit;
4729
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004730 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4731 value = value + 19;
4732 /* Convert the value from ascii to integer */
4733 ret = kstrtou8(value, 10, &roamScanControl);
4734 if (ret < 0)
4735 {
4736 /* If the input value is greater than max value of datatype, then also
4737 kstrtou8 fails */
4738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4739 "%s: kstrtou8 failed ", __func__);
4740 ret = -EINVAL;
4741 goto exit;
4742 }
4743
4744 if (0 != roamScanControl)
4745 {
4746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4747 "roam scan control invalid value = %d",
4748 roamScanControl);
4749 ret = -EINVAL;
4750 goto exit;
4751 }
4752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4753 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4754
4755 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4756 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004757#ifdef FEATURE_WLAN_OKC
4758 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4759 {
4760 tANI_U8 *value = command;
4761 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4762
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304763 ret = hdd_drv_cmd_validate(command, 10);
4764 if (ret)
4765 goto exit;
4766
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004767 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004768 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004769 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004770 hdd_is_okc_mode_enabled(pHddCtx) &&
4771 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4772 {
4773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004774 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004775 " hence this operation is not permitted!", __func__);
4776 ret = -EPERM;
4777 goto exit;
4778 }
4779
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004780 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4781 value = value + 11;
4782 /* Convert the value from ascii to integer */
4783 ret = kstrtou8(value, 10, &okcMode);
4784 if (ret < 0)
4785 {
4786 /* If the input value is greater than max value of datatype, then also
4787 kstrtou8 fails */
4788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4789 "%s: kstrtou8 failed range [%d - %d]", __func__,
4790 CFG_OKC_FEATURE_ENABLED_MIN,
4791 CFG_OKC_FEATURE_ENABLED_MAX);
4792 ret = -EINVAL;
4793 goto exit;
4794 }
4795
4796 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4797 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4798 {
4799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4800 "Okc mode value %d is out of range"
4801 " (Min: %d Max: %d)", okcMode,
4802 CFG_OKC_FEATURE_ENABLED_MIN,
4803 CFG_OKC_FEATURE_ENABLED_MAX);
4804 ret = -EINVAL;
4805 goto exit;
4806 }
4807
4808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4809 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4810
4811 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4812 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004813#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304814 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004815 {
4816 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4817 char extra[32];
4818 tANI_U8 len = 0;
4819
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004820 len = scnprintf(extra, sizeof(extra), "%s %d",
4821 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304822 len = VOS_MIN(priv_data.total_len, len + 1);
4823 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4825 "%s: failed to copy data to user buffer", __func__);
4826 ret = -EFAULT;
4827 goto exit;
4828 }
4829 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304830#ifdef WLAN_FEATURE_PACKET_FILTERING
4831 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4832 {
4833 tANI_U8 filterType = 0;
4834 tANI_U8 *value = command;
4835
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304836 ret = hdd_drv_cmd_validate(command, 21);
4837 if (ret)
4838 goto exit;
4839
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304840 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4841 value = value + 22;
4842
4843 /* Convert the value from ascii to integer */
4844 ret = kstrtou8(value, 10, &filterType);
4845 if (ret < 0)
4846 {
4847 /* If the input value is greater than max value of datatype,
4848 * then also kstrtou8 fails
4849 */
4850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4851 "%s: kstrtou8 failed range ", __func__);
4852 ret = -EINVAL;
4853 goto exit;
4854 }
4855
4856 if (filterType != 0 && filterType != 1)
4857 {
4858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4859 "%s: Accepted Values are 0 and 1 ", __func__);
4860 ret = -EINVAL;
4861 goto exit;
4862 }
4863 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4864 pAdapter->sessionId);
4865 }
4866#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304867 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4868 {
Kiet Lamad161252014-07-22 11:23:32 -07004869 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304870 int ret;
4871
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304872 ret = hdd_drv_cmd_validate(command, 10);
4873 if (ret)
4874 goto exit;
4875
Kiet Lamad161252014-07-22 11:23:32 -07004876 dhcpPhase = command + 11;
4877 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304878 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004880 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304881
4882 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004883
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304884 ret = wlan_hdd_scan_abort(pAdapter);
4885 if (ret < 0)
4886 {
4887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4888 FL("failed to abort existing scan %d"), ret);
4889 }
4890
Kiet Lamad161252014-07-22 11:23:32 -07004891 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4892 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304893 }
Kiet Lamad161252014-07-22 11:23:32 -07004894 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304895 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004897 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304898
4899 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004900
4901 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4902 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304903 }
4904 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004905 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4906 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304907 hddLog(LOG1,
4908 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304909 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004910 }
4911 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4912 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304913 hddLog(LOG1,
4914 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304915 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004916 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304917 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4918 {
4919 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4920 char extra[32];
4921 tANI_U8 len = 0;
4922
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304923 memset(extra, 0, sizeof(extra));
4924 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304925 len = VOS_MIN(priv_data.total_len, len + 1);
4926 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4928 "%s: failed to copy data to user buffer", __func__);
4929 ret = -EFAULT;
4930 goto exit;
4931 }
4932 ret = len;
4933 }
4934 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4935 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304936 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304937 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004938 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4939 {
4940 tANI_U8 filterType = 0;
4941 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304942
4943 ret = hdd_drv_cmd_validate(command, 8);
4944 if (ret)
4945 goto exit;
4946
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004947 value = command + 9;
4948
4949 /* Convert the value from ascii to integer */
4950 ret = kstrtou8(value, 10, &filterType);
4951 if (ret < 0)
4952 {
4953 /* If the input value is greater than max value of datatype,
4954 * then also kstrtou8 fails
4955 */
4956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4957 "%s: kstrtou8 failed range ", __func__);
4958 ret = -EINVAL;
4959 goto exit;
4960 }
4961 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4962 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4963 {
4964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4965 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4966 " 2-Sink ", __func__);
4967 ret = -EINVAL;
4968 goto exit;
4969 }
4970 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4971 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304972 pScanInfo = &pHddCtx->scan_info;
4973 if (filterType && pScanInfo != NULL &&
4974 pHddCtx->scan_info.mScanPending)
4975 {
4976 /*Miracast Session started. Abort Scan */
4977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4978 "%s, Aborting Scan For Miracast",__func__);
4979 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4980 eCSR_SCAN_ABORT_DEFAULT);
4981 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004982 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304983 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004984 }
Leo Chang614d2072013-08-22 14:59:44 -07004985 else if (strncmp(command, "SETMCRATE", 9) == 0)
4986 {
Leo Chang614d2072013-08-22 14:59:44 -07004987 tANI_U8 *value = command;
4988 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004989 tSirRateUpdateInd *rateUpdate;
4990 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004991
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304992 ret = hdd_drv_cmd_validate(command, 9);
4993 if (ret)
4994 goto exit;
4995
Leo Chang614d2072013-08-22 14:59:44 -07004996 /* Only valid for SAP mode */
4997 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4998 {
4999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5000 "%s: SAP mode is not running", __func__);
5001 ret = -EFAULT;
5002 goto exit;
5003 }
5004
5005 /* Move pointer to ahead of SETMCRATE<delimiter> */
5006 /* input value is in units of hundred kbps */
5007 value = value + 10;
5008 /* Convert the value from ascii to integer, decimal base */
5009 ret = kstrtouint(value, 10, &targetRate);
5010
Leo Chang1f98cbd2013-10-17 15:03:52 -07005011 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5012 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005013 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005014 hddLog(VOS_TRACE_LEVEL_ERROR,
5015 "%s: SETMCRATE indication alloc fail", __func__);
5016 ret = -EFAULT;
5017 goto exit;
5018 }
5019 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5020
5021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5022 "MC Target rate %d", targetRate);
5023 /* Ignore unicast */
5024 rateUpdate->ucastDataRate = -1;
5025 rateUpdate->mcastDataRate24GHz = targetRate;
5026 rateUpdate->mcastDataRate5GHz = targetRate;
5027 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5028 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5029 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5030 if (eHAL_STATUS_SUCCESS != status)
5031 {
5032 hddLog(VOS_TRACE_LEVEL_ERROR,
5033 "%s: SET_MC_RATE failed", __func__);
5034 vos_mem_free(rateUpdate);
5035 ret = -EFAULT;
5036 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005037 }
5038 }
jge35567202017-06-21 16:39:38 +08005039 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5040 {
5041 int status;
5042 int txPower;
5043 eHalStatus smeStatus;
5044 tANI_U8 *value = command;
5045 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5046 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5047
5048 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5049 if (status)
5050 {
5051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5052 "Invalid MAXTXPOWER command ");
5053 ret = -EINVAL;
5054 goto exit;
5055 }
5056
5057 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5058 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5059 txPower, MAC_ADDR_ARRAY(selfMac),
5060 MAC_ADDR_ARRAY(bssid));
5061 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5062 bssid, selfMac, txPower) ;
5063 if( smeStatus != eHAL_STATUS_SUCCESS )
5064 {
5065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5066 __func__);
5067 ret = -EINVAL;
5068 goto exit;
5069 }
5070
5071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5072 __func__);
5073 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305074#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005075 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305076 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005077 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305078 }
5079#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305080#ifdef WLAN_FEATURE_RMC
5081 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5082 (WLAN_HDD_IBSS == pAdapter->device_mode))
5083 {
5084 int i = 0;
5085 tANI_U8 *ibss_ie;
5086 tANI_U32 command_len;
5087 tANI_U8 *value = command;
5088 tHalHandle hHal = pHddCtx->hHal;
5089 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5090 tANI_U32 ibss_ie_length;
5091 tANI_U32 len, present;
5092 tANI_U8 *addIE;
5093 tANI_U8 *addIEData;
5094
5095 hddLog(LOG1,
5096 FL(" received command %s"),((char *) value));
5097 /* validate argument of command */
5098 if (strlen(value) <= 21)
5099 {
5100 hddLog(LOGE,
5101 FL("No arguements in command length %zu"), strlen(value));
5102 ret = -EFAULT;
5103 goto exit;
5104 }
5105
5106 /* moving to arguments of commands */
5107 value = value + 21;
5108 command_len = strlen(value);
5109
5110 /* oui_data can't be less than 3 bytes */
5111 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5112 {
5113 hddLog(LOGE,
5114 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5115 command_len);
5116 ret = -EFAULT;
5117 goto exit;
5118 }
5119 ibss_ie = vos_mem_malloc(command_len);
5120 if (!ibss_ie) {
5121 hddLog(LOGE,
5122 FL("Could not allocate memory for command length %d"),
5123 command_len);
5124 ret = -ENOMEM;
5125 goto exit;
5126 }
5127 vos_mem_zero(ibss_ie, command_len);
5128
5129 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5130 command_len);
5131 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5132 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5133 value, ibss_ie_length);
5134 ret = -EFAULT;
5135 vos_mem_free(ibss_ie);
5136 goto exit;
5137 }
5138
5139 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5140 while (i < ibss_ie_length)
5141 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5142
5143 /* Populate Vendor IE in Beacon */
5144 if ((ccmCfgGetInt(hHal,
5145 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5146 &present)) != eHAL_STATUS_SUCCESS)
5147 {
5148 hddLog(LOGE,
5149 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5150 ret = -EFAULT;
5151 vos_mem_free(ibss_ie);
5152 goto exit;
5153 }
5154
5155 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5156 if (!addIE) {
5157 hddLog(LOGE,
5158 FL("Could not allocate memory for command length %d"),
5159 command_len);
5160 vos_mem_free(ibss_ie);
5161 ret = -ENOMEM;
5162 goto exit;
5163 }
5164 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5165
5166 if (present)
5167 {
5168 if ((wlan_cfgGetStrLen(pMac,
5169 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5170 {
5171 hddLog(LOGE,
5172 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5173 ret = -EFAULT;
5174 vos_mem_free(ibss_ie);
5175 vos_mem_free(addIE);
5176 goto exit;
5177 }
5178
5179 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5180 ((len + ibss_ie_length) <=
5181 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5182 {
5183 if ((ccmCfgGetStr(hHal,
5184 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5185 != eHAL_STATUS_SUCCESS)
5186 {
5187 hddLog(LOGE,
5188 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5189 ret = -EFAULT;
5190 vos_mem_free(ibss_ie);
5191 vos_mem_free(addIE);
5192 goto exit;
5193 }
5194 else
5195 {
5196 /* Curruntly only WPA IE is added before Vendor IE
5197 * so we can blindly place the Vendor IE after WPA
5198 * IE. If no WPA IE found replace all with Vendor IE.
5199 */
5200 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5201 }
5202 }
5203 else
5204 {
5205 hddLog(LOGE,
5206 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5207 len, ibss_ie_length);
5208 ret = -EFAULT;
5209 vos_mem_free(addIE);
5210 vos_mem_free(ibss_ie);
5211 goto exit;
5212 }
5213 }
5214 else {
5215 len = 0;
5216 }
5217
5218 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5219 len += ibss_ie_length;
5220
5221 if (ccmCfgSetStr(hHal,
5222 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5223 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5224 {
5225 hddLog(LOGE,
5226 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5227 ret = -EFAULT;
5228 vos_mem_free(ibss_ie);
5229 vos_mem_free(addIE);
5230 goto exit;
5231 }
5232 vos_mem_free(addIE);
5233 if (ccmCfgSetInt(hHal,
5234 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5235 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5236 {
5237 hddLog(LOGE,
5238 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5239 ret = -EFAULT;
5240 vos_mem_free(ibss_ie);
5241 goto exit;
5242 }
5243
5244 /* Populate Vendor IE in probe resp */
5245 if ((ccmCfgGetInt(hHal,
5246 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5247 &present)) != eHAL_STATUS_SUCCESS)
5248 {
5249 hddLog(LOGE,
5250 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5251 ret = -EFAULT;
5252 vos_mem_free(ibss_ie);
5253 goto exit;
5254 }
5255
5256 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5257 if (!addIEData) {
5258 hddLog(LOGE,
5259 FL("Could not allocate memory for command length %d"),
5260 command_len);
5261 vos_mem_free(ibss_ie);
5262 ret = -ENOMEM;
5263 goto exit;
5264 }
5265 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5266
5267 if (present) {
5268 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5269 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5270 hddLog(LOGE,
5271 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5272 ret = -EFAULT;
5273 vos_mem_free(ibss_ie);
5274 vos_mem_free(addIEData);
5275 goto exit;
5276 }
5277 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5278 (ibss_ie_length + len) <=
5279 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5280
5281 if ((ccmCfgGetStr(hHal,
5282 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5283 != eHAL_STATUS_SUCCESS) {
5284 hddLog(LOGE,
5285 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5286 ret = -EFAULT;
5287 vos_mem_free(ibss_ie);
5288 vos_mem_free(addIEData);
5289 goto exit;
5290 }
5291 else {
5292 /* Curruntly only WPA IE is added before Vendor IE
5293 * so we can blindly place the Vendor IE after WPA
5294 * IE. If no WPA IE found replace all with Vendor IE.
5295 */
5296 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5297 }
5298 }
5299 else
5300 {
5301 hddLog(LOGE,
5302 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5303 len, ibss_ie_length);
5304 ret = -EFAULT;
5305 vos_mem_free(addIEData);
5306 vos_mem_free(ibss_ie);
5307 goto exit;
5308 }
5309 } /* probe rsp ADD IE present */
5310 else {
5311 /* probe rsp add IE is not present */
5312 len = 0;
5313 }
5314
5315 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5316 len += ibss_ie_length;
5317
5318 vos_mem_free(ibss_ie);
5319
5320 if (ccmCfgSetStr(hHal,
5321 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5322 (tANI_U8*)(addIEData),
5323 len, NULL,
5324 eANI_BOOLEAN_FALSE)
5325 == eHAL_STATUS_FAILURE) {
5326 hddLog(LOGE,
5327 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5328 ret = -EFAULT;
5329 vos_mem_free(addIEData);
5330 goto exit;
5331 }
5332 vos_mem_free(addIEData);
5333 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5334 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5335 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5336 {
5337 hddLog(LOGE,
5338 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5339 ret = -EFAULT;
5340 goto exit;
5341 }
5342 }
5343 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5344 {
5345 tANI_U8 *value = command;
5346 tANI_U8 ucRmcEnable = 0;
5347 int status;
5348
5349 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5350 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5351 {
5352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5353 "Received SETRMCENABLE command in invalid mode %d "
5354 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5355 pAdapter->device_mode);
5356 ret = -EINVAL;
5357 goto exit;
5358 }
5359
5360 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5361 if (status)
5362 {
5363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5364 "Invalid SETRMCENABLE command ");
5365 ret = -EINVAL;
5366 goto exit;
5367 }
5368
5369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5370 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5371
5372 if (TRUE == ucRmcEnable)
5373 {
5374 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5375 pAdapter->sessionId );
5376 }
5377 else if(FALSE == ucRmcEnable)
5378 {
5379 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5380 pAdapter->sessionId );
5381 }
5382 else
5383 {
5384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5385 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5386 ret = -EINVAL;
5387 goto exit;
5388 }
5389
5390 if (VOS_STATUS_SUCCESS != status)
5391 {
5392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5393 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5394 status);
5395 ret = -EINVAL;
5396 goto exit;
5397 }
5398 }
5399 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5400 {
5401 tANI_U8 *value = command;
5402 tANI_U32 uActionPeriod = 0;
5403 int status;
5404
5405 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5406 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5407 {
5408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5409 "Received SETRMC command in invalid mode %d "
5410 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5411 pAdapter->device_mode);
5412 ret = -EINVAL;
5413 goto exit;
5414 }
5415
5416 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5417 if (status)
5418 {
5419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5420 "Invalid SETRMCACTIONPERIOD command ");
5421 ret = -EINVAL;
5422 goto exit;
5423 }
5424
5425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5426 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5427
5428 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5429 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5430 {
5431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5432 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5433 ret = -EINVAL;
5434 goto exit;
5435 }
5436
5437 }
5438 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5439 {
5440 /* Peer Info All Command */
5441 int status = eHAL_STATUS_SUCCESS;
5442 hdd_station_ctx_t *pHddStaCtx = NULL;
5443 char *extra = NULL;
5444 int idx = 0, length = 0;
5445 v_MACADDR_t *macAddr;
5446 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5447
5448 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5449 {
5450 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5451 }
5452 else
5453 {
5454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5455 "%s: pAdapter is not valid for this device mode",
5456 __func__);
5457 ret = -EINVAL;
5458 goto exit;
5459 }
5460
5461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5462 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5463
5464
5465 /* Handle the command */
5466 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5467 if (VOS_STATUS_SUCCESS == status)
5468 {
5469 /* The variable extra needed to be allocated on the heap since
5470 * amount of memory required to copy the data for 32 devices
5471 * exceeds the size of 1024 bytes of default stack size. On
5472 * 64 bit devices, the default max stack size of 2048 bytes
5473 */
5474 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5475
5476 if (NULL == extra)
5477 {
5478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5479 "%s:kmalloc failed", __func__);
5480 ret = -EINVAL;
5481 goto exit;
5482 }
5483
5484 /* Copy number of stations */
5485 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5486 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5487 numOfBytestoPrint = length;
5488 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5489 {
5490 macAddr =
5491 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5492 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5493 if (NULL != macAddr)
5494 {
5495 txRateMbps =
5496 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5497
5498 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5499 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5500 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5501 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5502 (int)txRateMbps,
5503 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5504 }
5505 else
5506 {
5507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5508 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5509 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5510 }
5511
5512 /*
5513 * VOS_TRACE() macro has limitation of 512 bytes for the print
5514 * buffer. Hence printing the data in two chunks. The first chunk
5515 * will have the data for 16 devices and the second chunk will
5516 * have the rest.
5517 */
5518 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5519 {
5520 numOfBytestoPrint = length;
5521 }
5522 }
5523
5524 /*
5525 * Copy the data back into buffer, if the data to copy is
5526 * morethan 512 bytes than we will split the data and do
5527 * it in two shots
5528 */
5529 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5530 {
5531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5532 "%s: Copy into user data buffer failed ", __func__);
5533 ret = -EFAULT;
5534 kfree(extra);
5535 goto exit;
5536 }
5537 priv_data.buf[numOfBytestoPrint] = '\0';
5538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5539 "%s", priv_data.buf);
5540
5541 if (length > numOfBytestoPrint)
5542 {
5543 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5544 extra + numOfBytestoPrint,
5545 length - numOfBytestoPrint + 1))
5546 {
5547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5548 "%s: Copy into user data buffer failed ", __func__);
5549 ret = -EFAULT;
5550 kfree(extra);
5551 goto exit;
5552 }
5553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5554 "%s", &priv_data.buf[numOfBytestoPrint]);
5555 }
5556
5557 /* Free temporary buffer */
5558 kfree(extra);
5559 }
5560
5561 else
5562 {
5563 /* Command failed, log error */
5564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5565 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5566 __func__, status);
5567 ret = -EINVAL;
5568 goto exit;
5569 }
5570 ret = 0;
5571 }
5572 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5573 {
5574 /* Peer Info <Peer Addr> command */
5575 tANI_U8 *value = command;
5576 VOS_STATUS status;
5577 hdd_station_ctx_t *pHddStaCtx = NULL;
5578 char extra[128] = { 0 };
5579 v_U32_t length = 0;
5580 v_U8_t staIdx = 0;
5581 v_U32_t txRateMbps = 0;
5582 v_MACADDR_t peerMacAddr;
5583
5584 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5585 {
5586 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5587 }
5588 else
5589 {
5590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5591 "%s: pAdapter is not valid for this device mode",
5592 __func__);
5593 ret = -EINVAL;
5594 goto exit;
5595 }
5596
5597 /* if there are no peers, no need to continue with the command */
5598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5599 "%s: Received GETIBSSPEERINFO Command", __func__);
5600
5601 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5602 {
5603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5604 "%s:No IBSS Peers coalesced", __func__);
5605 ret = -EINVAL;
5606 goto exit;
5607 }
5608
5609 /* Parse the incoming command buffer */
5610 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5611 if (VOS_STATUS_SUCCESS != status)
5612 {
5613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5614 "%s: Invalid GETIBSSPEERINFO command", __func__);
5615 ret = -EINVAL;
5616 goto exit;
5617 }
5618
5619 /* Get station index for the peer mac address */
5620 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5621
5622 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5623 {
5624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5625 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5626 ret = -EINVAL;
5627 goto exit;
5628 }
5629
5630 /* Handle the command */
5631 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5632 if (VOS_STATUS_SUCCESS == status)
5633 {
5634 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5635 txRateMbps = (txRate * 500 * 1000)/1000000;
5636
5637 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5638 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5639
5640 /* Copy the data back into buffer */
5641 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5642 {
5643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5644 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5645 __func__);
5646 ret = -EFAULT;
5647 goto exit;
5648 }
5649 }
5650 else
5651 {
5652 /* Command failed, log error */
5653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5654 "%s: GETIBSSPEERINFO command failed with status code %d",
5655 __func__, status);
5656 ret = -EINVAL;
5657 goto exit;
5658 }
5659
5660 /* Success ! */
5661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5662 "%s", priv_data.buf);
5663 ret = 0;
5664 }
5665 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5666 {
5667 tANI_U8 *value = command;
5668 tANI_U32 uRate = 0;
5669 tTxrateinfoflags txFlags = 0;
5670 tSirRateUpdateInd *rateUpdateParams;
5671 int status;
5672
5673 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5674 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5675 {
5676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5677 "Received SETRMCTXRATE command in invalid mode %d "
5678 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5679 pAdapter->device_mode);
5680 ret = -EINVAL;
5681 goto exit;
5682 }
5683
5684 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5685 if (status)
5686 {
5687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5688 "Invalid SETRMCTXRATE command ");
5689 ret = -EINVAL;
5690 goto exit;
5691 }
5692
5693 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5694 if (NULL == rateUpdateParams)
5695 {
5696 ret = -EINVAL;
5697 goto exit;
5698 }
5699
5700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5701 "%s: uRate %d ", __func__, uRate);
5702
5703 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5704
5705 /* -1 implies ignore this param */
5706 rateUpdateParams->ucastDataRate = -1;
5707
5708 /*
5709 * Fill the user specifieed RMC rate param
5710 * and the derived tx flags.
5711 */
5712 rateUpdateParams->rmcDataRate = uRate;
5713 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5714
5715 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5716 }
5717 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5718 {
5719 char *value;
5720 tANI_U8 tx_fail_count = 0;
5721 tANI_U16 pid = 0;
5722
5723 value = command;
5724
5725 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5726
5727 if (0 != ret)
5728 {
5729 hddLog(VOS_TRACE_LEVEL_INFO,
5730 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5731 __func__);
5732 goto exit;
5733 }
5734
5735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5736 __func__, tx_fail_count, pid);
5737
5738 if (0 == tx_fail_count)
5739 {
5740 // Disable TX Fail Indication
5741 if (eHAL_STATUS_SUCCESS ==
5742 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5743 tx_fail_count,
5744 NULL))
5745 {
5746 cesium_pid = 0;
5747 }
5748 else
5749 {
5750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5751 "%s: failed to disable TX Fail Event ", __func__);
5752 ret = -EINVAL;
5753 }
5754 }
5755 else
5756 {
5757 if (eHAL_STATUS_SUCCESS ==
5758 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5759 tx_fail_count,
5760 (void*)hdd_tx_fail_ind_callback))
5761 {
5762 cesium_pid = pid;
5763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5764 "%s: Registered Cesium pid %u", __func__,
5765 cesium_pid);
5766 }
5767 else
5768 {
5769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5770 "%s: Failed to enable TX Fail Monitoring", __func__);
5771 ret = -EINVAL;
5772 }
5773 }
5774 }
5775
5776#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005777#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005778 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5779 {
5780 tANI_U8 *value = command;
5781 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5782 tANI_U8 numChannels = 0;
5783 eHalStatus status = eHAL_STATUS_SUCCESS;
5784
5785 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5786 if (eHAL_STATUS_SUCCESS != status)
5787 {
5788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5789 "%s: Failed to parse channel list information", __func__);
5790 ret = -EINVAL;
5791 goto exit;
5792 }
5793
5794 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5795 {
5796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5797 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5798 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5799 ret = -EINVAL;
5800 goto exit;
5801 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005802 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005803 ChannelList,
5804 numChannels);
5805 if (eHAL_STATUS_SUCCESS != status)
5806 {
5807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5808 "%s: Failed to update channel list information", __func__);
5809 ret = -EINVAL;
5810 goto exit;
5811 }
5812 }
5813 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5814 {
5815 tANI_U8 *value = command;
5816 char extra[128] = {0};
5817 int len = 0;
5818 tANI_U8 tid = 0;
5819 hdd_station_ctx_t *pHddStaCtx = NULL;
5820 tAniTrafStrmMetrics tsmMetrics;
5821 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5822
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305823 ret = hdd_drv_cmd_validate(command, 11);
5824 if (ret)
5825 goto exit;
5826
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005827 /* if not associated, return error */
5828 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5829 {
5830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5831 ret = -EINVAL;
5832 goto exit;
5833 }
5834
5835 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5836 value = value + 12;
5837 /* Convert the value from ascii to integer */
5838 ret = kstrtou8(value, 10, &tid);
5839 if (ret < 0)
5840 {
5841 /* If the input value is greater than max value of datatype, then also
5842 kstrtou8 fails */
5843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5844 "%s: kstrtou8 failed range [%d - %d]", __func__,
5845 TID_MIN_VALUE,
5846 TID_MAX_VALUE);
5847 ret = -EINVAL;
5848 goto exit;
5849 }
5850
5851 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5852 {
5853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5854 "tid value %d is out of range"
5855 " (Min: %d Max: %d)", tid,
5856 TID_MIN_VALUE,
5857 TID_MAX_VALUE);
5858 ret = -EINVAL;
5859 goto exit;
5860 }
5861
5862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5863 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5864
5865 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5866 {
5867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5868 "%s: failed to get tsm stats", __func__);
5869 ret = -EFAULT;
5870 goto exit;
5871 }
5872
5873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5874 "UplinkPktQueueDly(%d)\n"
5875 "UplinkPktQueueDlyHist[0](%d)\n"
5876 "UplinkPktQueueDlyHist[1](%d)\n"
5877 "UplinkPktQueueDlyHist[2](%d)\n"
5878 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305879 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005880 "UplinkPktLoss(%d)\n"
5881 "UplinkPktCount(%d)\n"
5882 "RoamingCount(%d)\n"
5883 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5884 tsmMetrics.UplinkPktQueueDlyHist[0],
5885 tsmMetrics.UplinkPktQueueDlyHist[1],
5886 tsmMetrics.UplinkPktQueueDlyHist[2],
5887 tsmMetrics.UplinkPktQueueDlyHist[3],
5888 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5889 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5890
5891 /* Output TSM stats is of the format
5892 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5893 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005894 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005895 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5896 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5897 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5898 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5899 tsmMetrics.RoamingDly);
5900
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305901 len = VOS_MIN(priv_data.total_len, len + 1);
5902 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5904 "%s: failed to copy data to user buffer", __func__);
5905 ret = -EFAULT;
5906 goto exit;
5907 }
5908 }
5909 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5910 {
5911 tANI_U8 *value = command;
5912 tANI_U8 *cckmIe = NULL;
5913 tANI_U8 cckmIeLen = 0;
5914 eHalStatus status = eHAL_STATUS_SUCCESS;
5915
5916 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5917 if (eHAL_STATUS_SUCCESS != status)
5918 {
5919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5920 "%s: Failed to parse cckm ie data", __func__);
5921 ret = -EINVAL;
5922 goto exit;
5923 }
5924
5925 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5926 {
5927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5928 "%s: CCKM Ie input length is more than max[%d]", __func__,
5929 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005930 vos_mem_free(cckmIe);
5931 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005932 ret = -EINVAL;
5933 goto exit;
5934 }
5935 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005936 vos_mem_free(cckmIe);
5937 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005938 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005939 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5940 {
5941 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005942 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005943 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005944
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005945 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005946 if (eHAL_STATUS_SUCCESS != status)
5947 {
5948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005949 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005950 ret = -EINVAL;
5951 goto exit;
5952 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005953 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5955 hdd_indicateEseBcnReportNoResults (pAdapter,
5956 eseBcnReq.bcnReq[0].measurementToken,
5957 0x02, //BIT(1) set for measurement done
5958 0); // no BSS
5959 goto exit;
5960 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005961
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005962 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5963 if (eHAL_STATUS_SUCCESS != status)
5964 {
5965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5966 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5967 ret = -EINVAL;
5968 goto exit;
5969 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005970 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005971#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305972 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5973 {
5974 eHalStatus status;
5975 char buf[32], len;
5976 long waitRet;
5977 bcnMissRateContext_t getBcnMissRateCtx;
5978
5979 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5980
5981 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5982 {
5983 hddLog(VOS_TRACE_LEVEL_WARN,
5984 FL("GETBCNMISSRATE: STA is not in connected state"));
5985 ret = -1;
5986 goto exit;
5987 }
5988
5989 init_completion(&(getBcnMissRateCtx.completion));
5990 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5991
5992 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5993 pAdapter->sessionId,
5994 (void *)getBcnMissRateCB,
5995 (void *)(&getBcnMissRateCtx));
5996 if( eHAL_STATUS_SUCCESS != status)
5997 {
5998 hddLog(VOS_TRACE_LEVEL_INFO,
5999 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6000 ret = -EINVAL;
6001 goto exit;
6002 }
6003
6004 waitRet = wait_for_completion_interruptible_timeout
6005 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
6006 if(waitRet <= 0)
6007 {
6008 hddLog(VOS_TRACE_LEVEL_ERROR,
6009 FL("failed to wait on bcnMissRateComp %d"), ret);
6010
6011 //Make magic number to zero so that callback is not called.
6012 spin_lock(&hdd_context_lock);
6013 getBcnMissRateCtx.magic = 0x0;
6014 spin_unlock(&hdd_context_lock);
6015 ret = -EINVAL;
6016 goto exit;
6017 }
6018
6019 hddLog(VOS_TRACE_LEVEL_INFO,
6020 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
6021
6022 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
6023 if (copy_to_user(priv_data.buf, &buf, len + 1))
6024 {
6025 hddLog(VOS_TRACE_LEVEL_ERROR,
6026 "%s: failed to copy data to user buffer", __func__);
6027 ret = -EFAULT;
6028 goto exit;
6029 }
6030 ret = len;
6031 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306032#ifdef FEATURE_WLAN_TDLS
6033 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6034 tANI_U8 *value = command;
6035 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306036
6037 ret = hdd_drv_cmd_validate(command, 26);
6038 if (ret)
6039 goto exit;
6040
Atul Mittal87ec2422014-09-24 13:12:50 +05306041 /* Move pointer to ahead of TDLSOFFCH*/
6042 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306043 if (!(sscanf(value, "%d", &set_value))) {
6044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6045 FL("No input identified"));
6046 ret = -EINVAL;
6047 goto exit;
6048 }
6049
Atul Mittal87ec2422014-09-24 13:12:50 +05306050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6051 "%s: Tdls offchannel offset:%d",
6052 __func__, set_value);
6053 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6054 if (ret < 0)
6055 {
6056 ret = -EINVAL;
6057 goto exit;
6058 }
6059
6060 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6061 tANI_U8 *value = command;
6062 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306063
6064 ret = hdd_drv_cmd_validate(command, 18);
6065 if (ret)
6066 goto exit;
6067
Atul Mittal87ec2422014-09-24 13:12:50 +05306068 /* Move pointer to ahead of tdlsoffchnmode*/
6069 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306070 ret = sscanf(value, "%d", &set_value);
6071 if (ret != 1) {
6072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6073 FL("No input identified"));
6074 ret = -EINVAL;
6075 goto exit;
6076 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6078 "%s: Tdls offchannel mode:%d",
6079 __func__, set_value);
6080 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6081 if (ret < 0)
6082 {
6083 ret = -EINVAL;
6084 goto exit;
6085 }
6086 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6087 tANI_U8 *value = command;
6088 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306089
6090 ret = hdd_drv_cmd_validate(command, 14);
6091 if (ret)
6092 goto exit;
6093
Atul Mittal87ec2422014-09-24 13:12:50 +05306094 /* Move pointer to ahead of TDLSOFFCH*/
6095 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306096 ret = sscanf(value, "%d", &set_value);
6097 if (ret != 1) {
6098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6099 "Wrong value is given for hdd_set_tdls_offchannel");
6100 ret = -EINVAL;
6101 goto exit;
6102 }
6103
Atul Mittal87ec2422014-09-24 13:12:50 +05306104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6105 "%s: Tdls offchannel num: %d",
6106 __func__, set_value);
6107 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6108 if (ret < 0)
6109 {
6110 ret = -EINVAL;
6111 goto exit;
6112 }
6113 }
6114#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306115 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6116 {
6117 eHalStatus status;
6118 char *buf = NULL;
6119 char len;
6120 long waitRet;
6121 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05306122 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306123 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306124 int stats;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306125
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306126 ret = hdd_drv_cmd_validate(command, 10);
6127 if (ret)
6128 goto exit;
6129
6130 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306131 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6132 if (!IS_FEATURE_FW_STATS_ENABLE)
6133 {
6134 hddLog(VOS_TRACE_LEVEL_INFO,
6135 FL("Get Firmware stats feature not supported"));
6136 ret = -EINVAL;
6137 goto exit;
6138 }
6139
6140 if (FW_STATS_MAX <= stats || 0 >= stats)
6141 {
6142 hddLog(VOS_TRACE_LEVEL_INFO,
6143 FL(" stats %d not supported"),stats);
6144 ret = -EINVAL;
6145 goto exit;
6146 }
6147
6148 init_completion(&(fwStatsCtx.completion));
6149 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
6150 fwStatsCtx.pAdapter = pAdapter;
6151 fwStatsRsp->type = 0;
6152 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05306153 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306154 if (eHAL_STATUS_SUCCESS != status)
6155 {
6156 hddLog(VOS_TRACE_LEVEL_ERROR,
6157 FL(" fail to post WDA cmd status = %d"), status);
6158 ret = -EINVAL;
6159 goto exit;
6160 }
6161 waitRet = wait_for_completion_timeout
6162 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
6163 if (waitRet <= 0)
6164 {
6165 hddLog(VOS_TRACE_LEVEL_ERROR,
6166 FL("failed to wait on GwtFwstats"));
6167 //Make magic number to zero so that callback is not executed.
6168 spin_lock(&hdd_context_lock);
6169 fwStatsCtx.magic = 0x0;
6170 spin_unlock(&hdd_context_lock);
6171 ret = -EINVAL;
6172 goto exit;
6173 }
6174 if (fwStatsRsp->type)
6175 {
6176 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6177 if (!buf)
6178 {
6179 hddLog(VOS_TRACE_LEVEL_ERROR,
6180 FL(" failed to allocate memory"));
6181 ret = -ENOMEM;
6182 goto exit;
6183 }
6184 switch( fwStatsRsp->type )
6185 {
6186 case FW_UBSP_STATS:
6187 {
6188 len = snprintf(buf, FW_STATE_RSP_LEN,
6189 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05306190 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
6191 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306192 }
6193 break;
6194 default:
6195 {
6196 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
6197 ret = -EFAULT;
6198 kfree(buf);
6199 goto exit;
6200 }
6201 }
6202 if (copy_to_user(priv_data.buf, buf, len + 1))
6203 {
6204 hddLog(VOS_TRACE_LEVEL_ERROR,
6205 FL(" failed to copy data to user buffer"));
6206 ret = -EFAULT;
6207 kfree(buf);
6208 goto exit;
6209 }
6210 ret = len;
6211 kfree(buf);
6212 }
6213 else
6214 {
6215 hddLog(VOS_TRACE_LEVEL_ERROR,
6216 FL("failed to fetch the stats"));
6217 ret = -EFAULT;
6218 goto exit;
6219 }
6220
6221 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306222 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
6223 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306224 ret = hdd_drv_cmd_validate(command, 15);
6225 if (ret)
6226 goto exit;
6227
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306228 /*
6229 * this command wld be called by user-space when it detects WLAN
6230 * ON after airplane mode is set. When APM is set, WLAN turns off.
6231 * But it can be turned back on. Otherwise; when APM is turned back
6232 * off, WLAN wld turn back on. So at that point the command is
6233 * expected to come down. 0 means disable, 1 means enable. The
6234 * constraint is removed when parameter 1 is set or different
6235 * country code is set
6236 */
6237 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
6238 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05306239 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
6240 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306241 ret = hdd_drv_cmd_validate(command, 16);
6242 if (ret)
6243 goto exit;
6244
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05306245 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
6246 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07006247 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306248 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6249 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
6250 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306251 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
6252 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07006253 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 }
6255exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306256 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 if (command)
6258 {
6259 kfree(command);
6260 }
6261 return ret;
6262}
6263
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006264#ifdef CONFIG_COMPAT
6265static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6266{
6267 struct {
6268 compat_uptr_t buf;
6269 int used_len;
6270 int total_len;
6271 } compat_priv_data;
6272 hdd_priv_data_t priv_data;
6273 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006274
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006275 /*
6276 * Note that pAdapter and ifr have already been verified by caller,
6277 * and HDD context has also been validated
6278 */
6279 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6280 sizeof(compat_priv_data))) {
6281 ret = -EFAULT;
6282 goto exit;
6283 }
6284 priv_data.buf = compat_ptr(compat_priv_data.buf);
6285 priv_data.used_len = compat_priv_data.used_len;
6286 priv_data.total_len = compat_priv_data.total_len;
6287 ret = hdd_driver_command(pAdapter, &priv_data);
6288 exit:
6289 return ret;
6290}
6291#else /* CONFIG_COMPAT */
6292static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6293{
6294 /* will never be invoked */
6295 return 0;
6296}
6297#endif /* CONFIG_COMPAT */
6298
6299static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6300{
6301 hdd_priv_data_t priv_data;
6302 int ret = 0;
6303
6304 /*
6305 * Note that pAdapter and ifr have already been verified by caller,
6306 * and HDD context has also been validated
6307 */
6308 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6309 ret = -EFAULT;
6310 } else {
6311 ret = hdd_driver_command(pAdapter, &priv_data);
6312 }
6313 return ret;
6314}
6315
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306316int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006317{
6318 hdd_adapter_t *pAdapter;
6319 hdd_context_t *pHddCtx;
6320 int ret;
6321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306322 ENTER();
6323
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006324 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6325 if (NULL == pAdapter) {
6326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6327 "%s: HDD adapter context is Null", __func__);
6328 ret = -ENODEV;
6329 goto exit;
6330 }
6331 if (dev != pAdapter->dev) {
6332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6333 "%s: HDD adapter/dev inconsistency", __func__);
6334 ret = -ENODEV;
6335 goto exit;
6336 }
6337
6338 if ((!ifr) || (!ifr->ifr_data)) {
6339 ret = -EINVAL;
6340 goto exit;
6341 }
6342
6343 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6344 ret = wlan_hdd_validate_context(pHddCtx);
6345 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006346 ret = -EBUSY;
6347 goto exit;
6348 }
6349
6350 switch (cmd) {
6351 case (SIOCDEVPRIVATE + 1):
6352 if (is_compat_task())
6353 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6354 else
6355 ret = hdd_driver_ioctl(pAdapter, ifr);
6356 break;
6357 default:
6358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6359 __func__, cmd);
6360 ret = -EINVAL;
6361 break;
6362 }
6363 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306364 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006365 return ret;
6366}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006367
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306368int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6369{
6370 int ret;
6371
6372 vos_ssr_protect(__func__);
6373 ret = __hdd_ioctl(dev, ifr, cmd);
6374 vos_ssr_unprotect(__func__);
6375
6376 return ret;
6377}
6378
Katya Nigame7b69a82015-04-28 15:24:06 +05306379int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6380{
6381 return 0;
6382}
6383
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006384#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006385/**---------------------------------------------------------------------------
6386
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006387 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006388
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006389 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006390 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6391 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6392 <space>Scan Mode N<space>Meas Duration N
6393 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6394 then take N.
6395 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6396 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6397 This function does not take care of removing duplicate channels from the list
6398
6399 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006400 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006401
6402 \return - 0 for success non-zero for failure
6403
6404 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006405static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6406 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006407{
6408 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306409 uint8_t input = 0;
6410 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006411 int j = 0, i = 0, v = 0;
6412 char buf[32];
6413
6414 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6415 /*no argument after the command*/
6416 if (NULL == inPtr)
6417 {
6418 return -EINVAL;
6419 }
6420 /*no space after the command*/
6421 else if (SPACE_ASCII_VALUE != *inPtr)
6422 {
6423 return -EINVAL;
6424 }
6425
6426 /*removing empty spaces*/
6427 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6428
6429 /*no argument followed by spaces*/
6430 if ('\0' == *inPtr) return -EINVAL;
6431
6432 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006433 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006434 if (1 != v) return -EINVAL;
6435
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306436 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006437 if ( v < 0) return -EINVAL;
6438
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306439 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
6440 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006441
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306442 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6443
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006444
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006445 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006446 {
6447 for (i = 0; i < 4; i++)
6448 {
6449 /*inPtr pointing to the beginning of first space after number of ie fields*/
6450 inPtr = strpbrk( inPtr, " " );
6451 /*no ie data after the number of ie fields argument*/
6452 if (NULL == inPtr) return -EINVAL;
6453
6454 /*removing empty space*/
6455 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6456
6457 /*no ie data after the number of ie fields argument and spaces*/
6458 if ( '\0' == *inPtr ) return -EINVAL;
6459
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006460 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006461 if (1 != v) return -EINVAL;
6462
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306463 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006464 if (v < 0) return -EINVAL;
6465
6466 switch (i)
6467 {
6468 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306469 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006470 {
6471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306472 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006473 return -EINVAL;
6474 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006475 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006476 break;
6477
6478 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306479 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006480 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6481 {
6482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306483 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006484 return -EINVAL;
6485 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006486 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006487 break;
6488
6489 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006490 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006491 {
6492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306493 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006494 return -EINVAL;
6495 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006496 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006497 break;
6498
6499 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306500 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6501 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006502 {
6503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306504 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006505 return -EINVAL;
6506 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006507 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006508 break;
6509 }
6510 }
6511 }
6512
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006513 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006514 {
6515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306516 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006517 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006518 pEseBcnReq->bcnReq[j].measurementToken,
6519 pEseBcnReq->bcnReq[j].channel,
6520 pEseBcnReq->bcnReq[j].scanMode,
6521 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006522 }
6523
6524 return VOS_STATUS_SUCCESS;
6525}
6526
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006527static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6528{
6529 struct statsContext *pStatsContext = NULL;
6530 hdd_adapter_t *pAdapter = NULL;
6531
6532 if (NULL == pContext)
6533 {
6534 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07006535 "%s: Bad param, pContext [%pK]",
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006536 __func__, pContext);
6537 return;
6538 }
6539
Jeff Johnson72a40512013-12-19 10:14:15 -08006540 /* there is a race condition that exists between this callback
6541 function and the caller since the caller could time out either
6542 before or while this code is executing. we use a spinlock to
6543 serialize these actions */
6544 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006545
6546 pStatsContext = pContext;
6547 pAdapter = pStatsContext->pAdapter;
6548 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6549 {
6550 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006551 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006552 hddLog(VOS_TRACE_LEVEL_WARN,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07006553 "%s: Invalid context, pAdapter [%pK] magic [%08x]",
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006554 __func__, pAdapter, pStatsContext->magic);
6555 return;
6556 }
6557
Jeff Johnson72a40512013-12-19 10:14:15 -08006558 /* context is valid so caller is still waiting */
6559
6560 /* paranoia: invalidate the magic */
6561 pStatsContext->magic = 0;
6562
6563 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006564 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6565 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6566 tsmMetrics.UplinkPktQueueDlyHist,
6567 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6568 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6569 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6570 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6571 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6572 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6573 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6574
Jeff Johnson72a40512013-12-19 10:14:15 -08006575 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006576 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006577
6578 /* serialization is complete */
6579 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006580}
6581
6582
6583
6584static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6585 tAniTrafStrmMetrics* pTsmMetrics)
6586{
6587 hdd_station_ctx_t *pHddStaCtx = NULL;
6588 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006589 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006590 long lrc;
6591 struct statsContext context;
6592 hdd_context_t *pHddCtx = NULL;
6593
6594 if (NULL == pAdapter)
6595 {
6596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6597 return VOS_STATUS_E_FAULT;
6598 }
6599
6600 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6602
6603 /* we are connected prepare our callback context */
6604 init_completion(&context.completion);
6605 context.pAdapter = pAdapter;
6606 context.magic = STATS_CONTEXT_MAGIC;
6607
6608 /* query tsm stats */
6609 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6610 pHddStaCtx->conn_info.staId[ 0 ],
6611 pHddStaCtx->conn_info.bssId,
6612 &context, pHddCtx->pvosContext, tid);
6613
6614 if (eHAL_STATUS_SUCCESS != hstatus)
6615 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6617 __func__);
6618 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006619 }
6620 else
6621 {
6622 /* request was sent -- wait for the response */
6623 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6624 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006625 if (lrc <= 0)
6626 {
6627 hddLog(VOS_TRACE_LEVEL_ERROR,
6628 "%s: SME %s while retrieving statistics",
6629 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006630 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006631 }
6632 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006633
Jeff Johnson72a40512013-12-19 10:14:15 -08006634 /* either we never sent a request, we sent a request and received a
6635 response or we sent a request and timed out. if we never sent a
6636 request or if we sent a request and got a response, we want to
6637 clear the magic out of paranoia. if we timed out there is a
6638 race condition such that the callback function could be
6639 executing at the same time we are. of primary concern is if the
6640 callback function had already verified the "magic" but had not
6641 yet set the completion variable when a timeout occurred. we
6642 serialize these activities by invalidating the magic while
6643 holding a shared spinlock which will cause us to block if the
6644 callback is currently executing */
6645 spin_lock(&hdd_context_lock);
6646 context.magic = 0;
6647 spin_unlock(&hdd_context_lock);
6648
6649 if (VOS_STATUS_SUCCESS == vstatus)
6650 {
6651 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6652 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6653 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6654 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6655 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6656 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6657 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6658 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6659 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6660 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6661 }
6662 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006663}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006664#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006665
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006666#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006667void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6668{
6669 eCsrBand band = -1;
6670 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6671 switch (band)
6672 {
6673 case eCSR_BAND_ALL:
6674 *pBand = WLAN_HDD_UI_BAND_AUTO;
6675 break;
6676
6677 case eCSR_BAND_24:
6678 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6679 break;
6680
6681 case eCSR_BAND_5G:
6682 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6683 break;
6684
6685 default:
6686 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6687 *pBand = -1;
6688 break;
6689 }
6690}
6691
6692/**---------------------------------------------------------------------------
6693
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006694 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6695
6696 This function parses the send action frame data passed in the format
6697 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6698
Srinivas Girigowda56076852013-08-20 14:00:50 -07006699 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006700 \param - pTargetApBssid Pointer to target Ap bssid
6701 \param - pChannel Pointer to the Target AP channel
6702 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6703 \param - pBuf Pointer to data
6704 \param - pBufLen Pointer to data length
6705
6706 \return - 0 for success non-zero for failure
6707
6708 --------------------------------------------------------------------------*/
6709VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6710 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6711{
6712 tANI_U8 *inPtr = pValue;
6713 tANI_U8 *dataEnd;
6714 int tempInt;
6715 int j = 0;
6716 int i = 0;
6717 int v = 0;
6718 tANI_U8 tempBuf[32];
6719 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006720 /* 12 hexa decimal digits, 5 ':' and '\0' */
6721 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006722
6723 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6724 /*no argument after the command*/
6725 if (NULL == inPtr)
6726 {
6727 return -EINVAL;
6728 }
6729
6730 /*no space after the command*/
6731 else if (SPACE_ASCII_VALUE != *inPtr)
6732 {
6733 return -EINVAL;
6734 }
6735
6736 /*removing empty spaces*/
6737 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6738
6739 /*no argument followed by spaces*/
6740 if ('\0' == *inPtr)
6741 {
6742 return -EINVAL;
6743 }
6744
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006745 v = sscanf(inPtr, "%17s", macAddress);
6746 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006747 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6749 "Invalid MAC address or All hex inputs are not read (%d)", v);
6750 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006751 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006752
6753 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6754 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6755 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6756 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6757 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6758 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006759
6760 /* point to the next argument */
6761 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6762 /*no argument after the command*/
6763 if (NULL == inPtr) return -EINVAL;
6764
6765 /*removing empty spaces*/
6766 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6767
6768 /*no argument followed by spaces*/
6769 if ('\0' == *inPtr)
6770 {
6771 return -EINVAL;
6772 }
6773
6774 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006775 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006776 if (1 != v) return -EINVAL;
6777
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006778 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306779 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306780 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006781
6782 *pChannel = tempInt;
6783
6784 /* point to the next argument */
6785 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6786 /*no argument after the command*/
6787 if (NULL == inPtr) return -EINVAL;
6788 /*removing empty spaces*/
6789 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6790
6791 /*no argument followed by spaces*/
6792 if ('\0' == *inPtr)
6793 {
6794 return -EINVAL;
6795 }
6796
6797 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006798 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006799 if (1 != v) return -EINVAL;
6800
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006801 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006802 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006803
6804 *pDwellTime = tempInt;
6805
6806 /* point to the next argument */
6807 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6808 /*no argument after the command*/
6809 if (NULL == inPtr) return -EINVAL;
6810 /*removing empty spaces*/
6811 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6812
6813 /*no argument followed by spaces*/
6814 if ('\0' == *inPtr)
6815 {
6816 return -EINVAL;
6817 }
6818
6819 /* find the length of data */
6820 dataEnd = inPtr;
6821 while(('\0' != *dataEnd) )
6822 {
6823 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006824 }
Kiet Lambe150c22013-11-21 16:30:32 +05306825 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006826 if ( *pBufLen <= 0) return -EINVAL;
6827
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006828 /* Allocate the number of bytes based on the number of input characters
6829 whether it is even or odd.
6830 if the number of input characters are even, then we need N/2 byte.
6831 if the number of input characters are odd, then we need do (N+1)/2 to
6832 compensate rounding off.
6833 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6834 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6835 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006836 if (NULL == *pBuf)
6837 {
6838 hddLog(VOS_TRACE_LEVEL_FATAL,
6839 "%s: vos_mem_alloc failed ", __func__);
6840 return -EINVAL;
6841 }
6842
6843 /* the buffer received from the upper layer is character buffer,
6844 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6845 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6846 and f0 in 3rd location */
6847 for (i = 0, j = 0; j < *pBufLen; j += 2)
6848 {
Kiet Lambe150c22013-11-21 16:30:32 +05306849 if( j+1 == *pBufLen)
6850 {
6851 tempByte = hdd_parse_hex(inPtr[j]);
6852 }
6853 else
6854 {
6855 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6856 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006857 (*pBuf)[i++] = tempByte;
6858 }
6859 *pBufLen = i;
6860 return VOS_STATUS_SUCCESS;
6861}
6862
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006863/**---------------------------------------------------------------------------
6864
Srinivas Girigowdade697412013-02-14 16:31:48 -08006865 \brief hdd_parse_channellist() - HDD Parse channel list
6866
6867 This function parses the channel list passed in the format
6868 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006869 if the Number of channels (N) does not match with the actual number of channels passed
6870 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6871 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6872 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6873 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006874
6875 \param - pValue Pointer to input channel list
6876 \param - ChannelList Pointer to local output array to record channel list
6877 \param - pNumChannels Pointer to number of roam scan channels
6878
6879 \return - 0 for success non-zero for failure
6880
6881 --------------------------------------------------------------------------*/
6882VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6883{
6884 tANI_U8 *inPtr = pValue;
6885 int tempInt;
6886 int j = 0;
6887 int v = 0;
6888 char buf[32];
6889
6890 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6891 /*no argument after the command*/
6892 if (NULL == inPtr)
6893 {
6894 return -EINVAL;
6895 }
6896
6897 /*no space after the command*/
6898 else if (SPACE_ASCII_VALUE != *inPtr)
6899 {
6900 return -EINVAL;
6901 }
6902
6903 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006904 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006905
6906 /*no argument followed by spaces*/
6907 if ('\0' == *inPtr)
6908 {
6909 return -EINVAL;
6910 }
6911
6912 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006913 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006914 if (1 != v) return -EINVAL;
6915
Srinivas Girigowdade697412013-02-14 16:31:48 -08006916 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006917 if ((v < 0) ||
6918 (tempInt <= 0) ||
6919 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6920 {
6921 return -EINVAL;
6922 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006923
6924 *pNumChannels = tempInt;
6925
6926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6927 "Number of channels are: %d", *pNumChannels);
6928
6929 for (j = 0; j < (*pNumChannels); j++)
6930 {
6931 /*inPtr pointing to the beginning of first space after number of channels*/
6932 inPtr = strpbrk( inPtr, " " );
6933 /*no channel list after the number of channels argument*/
6934 if (NULL == inPtr)
6935 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006936 if (0 != j)
6937 {
6938 *pNumChannels = j;
6939 return VOS_STATUS_SUCCESS;
6940 }
6941 else
6942 {
6943 return -EINVAL;
6944 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006945 }
6946
6947 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006948 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006949
6950 /*no channel list after the number of channels argument and spaces*/
6951 if ( '\0' == *inPtr )
6952 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006953 if (0 != j)
6954 {
6955 *pNumChannels = j;
6956 return VOS_STATUS_SUCCESS;
6957 }
6958 else
6959 {
6960 return -EINVAL;
6961 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006962 }
6963
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006964 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006965 if (1 != v) return -EINVAL;
6966
Srinivas Girigowdade697412013-02-14 16:31:48 -08006967 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006968 if ((v < 0) ||
6969 (tempInt <= 0) ||
6970 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6971 {
6972 return -EINVAL;
6973 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006974 pChannelList[j] = tempInt;
6975
6976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6977 "Channel %d added to preferred channel list",
6978 pChannelList[j] );
6979 }
6980
Srinivas Girigowdade697412013-02-14 16:31:48 -08006981 return VOS_STATUS_SUCCESS;
6982}
6983
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006984
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306985/**
6986 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
6987 * This function parses the reasoc command data passed in the format
6988 * REASSOC<space><bssid><space><channel>
6989 *
6990 * @pValue: Pointer to input data (its a NUL terminated string)
6991 * @pTargetApBssid: Pointer to target Ap bssid
6992 * @pChannel: Pointer to the Target AP channel
6993 *
6994 * Return: 0 for success non-zero for failure
6995 */
6996static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
6997 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006998{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306999 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007000 int tempInt;
7001 int v = 0;
7002 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007003 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007004 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007005
7006 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7007 /*no argument after the command*/
7008 if (NULL == inPtr)
7009 {
7010 return -EINVAL;
7011 }
7012
7013 /*no space after the command*/
7014 else if (SPACE_ASCII_VALUE != *inPtr)
7015 {
7016 return -EINVAL;
7017 }
7018
7019 /*removing empty spaces*/
7020 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7021
7022 /*no argument followed by spaces*/
7023 if ('\0' == *inPtr)
7024 {
7025 return -EINVAL;
7026 }
7027
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007028 v = sscanf(inPtr, "%17s", macAddress);
7029 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007030 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7032 "Invalid MAC address or All hex inputs are not read (%d)", v);
7033 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007034 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007035
7036 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7037 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7038 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7039 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7040 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7041 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007042
7043 /* point to the next argument */
7044 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7045 /*no argument after the command*/
7046 if (NULL == inPtr) return -EINVAL;
7047
7048 /*removing empty spaces*/
7049 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7050
7051 /*no argument followed by spaces*/
7052 if ('\0' == *inPtr)
7053 {
7054 return -EINVAL;
7055 }
7056
7057 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007058 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007059 if (1 != v) return -EINVAL;
7060
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007061 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007062 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307063 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007064 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7065 {
7066 return -EINVAL;
7067 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007068
7069 *pChannel = tempInt;
7070 return VOS_STATUS_SUCCESS;
7071}
7072
7073#endif
7074
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007075#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007076/**---------------------------------------------------------------------------
7077
7078 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7079
7080 This function parses the SETCCKM IE command
7081 SETCCKMIE<space><ie data>
7082
7083 \param - pValue Pointer to input data
7084 \param - pCckmIe Pointer to output cckm Ie
7085 \param - pCckmIeLen Pointer to output cckm ie length
7086
7087 \return - 0 for success non-zero for failure
7088
7089 --------------------------------------------------------------------------*/
7090VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7091 tANI_U8 *pCckmIeLen)
7092{
7093 tANI_U8 *inPtr = pValue;
7094 tANI_U8 *dataEnd;
7095 int j = 0;
7096 int i = 0;
7097 tANI_U8 tempByte = 0;
7098
7099 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7100 /*no argument after the command*/
7101 if (NULL == inPtr)
7102 {
7103 return -EINVAL;
7104 }
7105
7106 /*no space after the command*/
7107 else if (SPACE_ASCII_VALUE != *inPtr)
7108 {
7109 return -EINVAL;
7110 }
7111
7112 /*removing empty spaces*/
7113 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7114
7115 /*no argument followed by spaces*/
7116 if ('\0' == *inPtr)
7117 {
7118 return -EINVAL;
7119 }
7120
7121 /* find the length of data */
7122 dataEnd = inPtr;
7123 while(('\0' != *dataEnd) )
7124 {
7125 dataEnd++;
7126 ++(*pCckmIeLen);
7127 }
7128 if ( *pCckmIeLen <= 0) return -EINVAL;
7129
7130 /* Allocate the number of bytes based on the number of input characters
7131 whether it is even or odd.
7132 if the number of input characters are even, then we need N/2 byte.
7133 if the number of input characters are odd, then we need do (N+1)/2 to
7134 compensate rounding off.
7135 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7136 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7137 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7138 if (NULL == *pCckmIe)
7139 {
7140 hddLog(VOS_TRACE_LEVEL_FATAL,
7141 "%s: vos_mem_alloc failed ", __func__);
7142 return -EINVAL;
7143 }
7144 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7145 /* the buffer received from the upper layer is character buffer,
7146 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7147 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7148 and f0 in 3rd location */
7149 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7150 {
7151 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7152 (*pCckmIe)[i++] = tempByte;
7153 }
7154 *pCckmIeLen = i;
7155
7156 return VOS_STATUS_SUCCESS;
7157}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007158#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007159
Jeff Johnson295189b2012-06-20 16:38:30 -07007160/**---------------------------------------------------------------------------
7161
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007162 \brief hdd_is_valid_mac_address() - Validate MAC address
7163
7164 This function validates whether the given MAC address is valid or not
7165 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7166 where X is the hexa decimal digit character and separated by ':'
7167 This algorithm works even if MAC address is not separated by ':'
7168
7169 This code checks given input string mac contains exactly 12 hexadecimal digits.
7170 and a separator colon : appears in the input string only after
7171 an even number of hex digits.
7172
7173 \param - pMacAddr pointer to the input MAC address
7174 \return - 1 for valid and 0 for invalid
7175
7176 --------------------------------------------------------------------------*/
7177
7178v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7179{
7180 int xdigit = 0;
7181 int separator = 0;
7182 while (*pMacAddr)
7183 {
7184 if (isxdigit(*pMacAddr))
7185 {
7186 xdigit++;
7187 }
7188 else if (':' == *pMacAddr)
7189 {
7190 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
7191 break;
7192
7193 ++separator;
7194 }
7195 else
7196 {
7197 separator = -1;
7198 /* Invalid MAC found */
7199 return 0;
7200 }
7201 ++pMacAddr;
7202 }
7203 return (xdigit == 12 && (separator == 5 || separator == 0));
7204}
7205
7206/**---------------------------------------------------------------------------
7207
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307208 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07007209
7210 \param - dev Pointer to net_device structure
7211
7212 \return - 0 for success non-zero for failure
7213
7214 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307215int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007216{
7217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7218 hdd_context_t *pHddCtx;
7219 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7220 VOS_STATUS status;
7221 v_BOOL_t in_standby = TRUE;
7222
7223 if (NULL == pAdapter)
7224 {
7225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307226 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 return -ENODEV;
7228 }
7229
7230 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307231 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
7232 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 if (NULL == pHddCtx)
7234 {
7235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007236 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 return -ENODEV;
7238 }
7239
7240 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7241 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7242 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007243 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7244 {
7245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307246 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007247 in_standby = FALSE;
7248 break;
7249 }
7250 else
7251 {
7252 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7253 pAdapterNode = pNext;
7254 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 }
7256
7257 if (TRUE == in_standby)
7258 {
7259 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
7260 {
7261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
7262 "wlan out of power save", __func__);
7263 return -EINVAL;
7264 }
7265 }
7266
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007267 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
7269 {
7270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007271 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007274 netif_tx_start_all_queues(dev);
7275 }
7276
7277 return 0;
7278}
7279
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307280/**---------------------------------------------------------------------------
7281
7282 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7283
7284 This is called in response to ifconfig up
7285
7286 \param - dev Pointer to net_device structure
7287
7288 \return - 0 for success non-zero for failure
7289
7290 --------------------------------------------------------------------------*/
7291int hdd_open(struct net_device *dev)
7292{
7293 int ret;
7294
7295 vos_ssr_protect(__func__);
7296 ret = __hdd_open(dev);
7297 vos_ssr_unprotect(__func__);
7298
7299 return ret;
7300}
7301
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307302int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007303{
7304 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7305
7306 if(pAdapter == NULL) {
7307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007308 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007309 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 }
7311
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 return 0;
7313}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307314
7315int hdd_mon_open (struct net_device *dev)
7316{
7317 int ret;
7318
7319 vos_ssr_protect(__func__);
7320 ret = __hdd_mon_open(dev);
7321 vos_ssr_unprotect(__func__);
7322
7323 return ret;
7324}
7325
Katya Nigame7b69a82015-04-28 15:24:06 +05307326int hdd_mon_stop(struct net_device *dev)
7327{
7328 return 0;
7329}
7330
Jeff Johnson295189b2012-06-20 16:38:30 -07007331/**---------------------------------------------------------------------------
7332
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307333 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007334
7335 \param - dev Pointer to net_device structure
7336
7337 \return - 0 for success non-zero for failure
7338
7339 --------------------------------------------------------------------------*/
7340
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307341int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007342{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307343 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7345 hdd_context_t *pHddCtx;
7346 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7347 VOS_STATUS status;
7348 v_BOOL_t enter_standby = TRUE;
7349
7350 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 if (NULL == pAdapter)
7352 {
7353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307354 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 return -ENODEV;
7356 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307357 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307358 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307359
7360 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7361 ret = wlan_hdd_validate_context(pHddCtx);
7362 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007363 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307364 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 }
7366
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307367 /* Nothing to be done if the interface is not opened */
7368 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7369 {
7370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7371 "%s: NETDEV Interface is not OPENED", __func__);
7372 return -ENODEV;
7373 }
7374
7375 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007376 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307378
7379 /* Disable TX on the interface, after this hard_start_xmit() will not
7380 * be called on that interface
7381 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307382 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307384
7385 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007386 netif_carrier_off(pAdapter->dev);
7387
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307388 /* The interface is marked as down for outside world (aka kernel)
7389 * But the driver is pretty much alive inside. The driver needs to
7390 * tear down the existing connection on the netdev (session)
7391 * cleanup the data pipes and wait until the control plane is stabilized
7392 * for this interface. The call also needs to wait until the above
7393 * mentioned actions are completed before returning to the caller.
7394 * Notice that the hdd_stop_adapter is requested not to close the session
7395 * That is intentional to be able to scan if it is a STA/P2P interface
7396 */
7397 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307398#ifdef FEATURE_WLAN_TDLS
7399 mutex_lock(&pHddCtx->tdls_lock);
7400#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307401 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307402 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307403#ifdef FEATURE_WLAN_TDLS
7404 mutex_unlock(&pHddCtx->tdls_lock);
7405#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 /* SoftAP ifaces should never go in power save mode
7407 making sure same here. */
7408 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7409 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 )
7412 {
7413 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7415 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007416 EXIT();
7417 return 0;
7418 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307419 /* Find if any iface is up. If any iface is up then can't put device to
7420 * sleep/power save mode
7421 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7423 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7424 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007425 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7426 {
7427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307428 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007429 enter_standby = FALSE;
7430 break;
7431 }
7432 else
7433 {
7434 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7435 pAdapterNode = pNext;
7436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007437 }
7438
7439 if (TRUE == enter_standby)
7440 {
7441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7442 "entering standby", __func__);
7443 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7444 {
7445 /*log and return success*/
7446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7447 "wlan in power save", __func__);
7448 }
7449 }
7450
7451 EXIT();
7452 return 0;
7453}
7454
7455/**---------------------------------------------------------------------------
7456
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307457 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007458
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307459 This is called in response to ifconfig down
7460
7461 \param - dev Pointer to net_device structure
7462
7463 \return - 0 for success non-zero for failure
7464-----------------------------------------------------------------------------*/
7465int hdd_stop (struct net_device *dev)
7466{
7467 int ret;
7468
7469 vos_ssr_protect(__func__);
7470 ret = __hdd_stop(dev);
7471 vos_ssr_unprotect(__func__);
7472
7473 return ret;
7474}
7475
7476/**---------------------------------------------------------------------------
7477
7478 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007479
7480 \param - dev Pointer to net_device structure
7481
7482 \return - void
7483
7484 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307485static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007486{
7487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307488 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 ENTER();
7490
7491 do
7492 {
7493 if (NULL == pAdapter)
7494 {
7495 hddLog(VOS_TRACE_LEVEL_FATAL,
7496 "%s: NULL pAdapter", __func__);
7497 break;
7498 }
7499
7500 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7501 {
7502 hddLog(VOS_TRACE_LEVEL_FATAL,
7503 "%s: Invalid magic", __func__);
7504 break;
7505 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7507 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 {
7509 hddLog(VOS_TRACE_LEVEL_FATAL,
7510 "%s: NULL pHddCtx", __func__);
7511 break;
7512 }
7513
7514 if (dev != pAdapter->dev)
7515 {
7516 hddLog(VOS_TRACE_LEVEL_FATAL,
7517 "%s: Invalid device reference", __func__);
7518 /* we haven't validated all cases so let this go for now */
7519 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307520#ifdef FEATURE_WLAN_TDLS
7521 mutex_lock(&pHddCtx->tdls_lock);
7522#endif
c_hpothu002231a2015-02-05 14:58:51 +05307523 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307524#ifdef FEATURE_WLAN_TDLS
7525 mutex_unlock(&pHddCtx->tdls_lock);
7526#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007527
7528 /* after uninit our adapter structure will no longer be valid */
7529 pAdapter->dev = NULL;
7530 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307531 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 } while (0);
7533
7534 EXIT();
7535}
7536
7537/**---------------------------------------------------------------------------
7538
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307539 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7540
7541 This is called during the netdev unregister to uninitialize all data
7542associated with the device
7543
7544 \param - dev Pointer to net_device structure
7545
7546 \return - void
7547
7548 --------------------------------------------------------------------------*/
7549static void hdd_uninit (struct net_device *dev)
7550{
7551 vos_ssr_protect(__func__);
7552 __hdd_uninit(dev);
7553 vos_ssr_unprotect(__func__);
7554}
7555
7556/**---------------------------------------------------------------------------
7557
Jeff Johnson295189b2012-06-20 16:38:30 -07007558 \brief hdd_release_firmware() -
7559
7560 This function calls the release firmware API to free the firmware buffer.
7561
7562 \param - pFileName Pointer to the File Name.
7563 pCtx - Pointer to the adapter .
7564
7565
7566 \return - 0 for success, non zero for failure
7567
7568 --------------------------------------------------------------------------*/
7569
7570VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7571{
7572 VOS_STATUS status = VOS_STATUS_SUCCESS;
7573 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7574 ENTER();
7575
7576
7577 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7578
7579 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7580
7581 if(pHddCtx->fw) {
7582 release_firmware(pHddCtx->fw);
7583 pHddCtx->fw = NULL;
7584 }
7585 else
7586 status = VOS_STATUS_E_FAILURE;
7587 }
7588 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7589 if(pHddCtx->nv) {
7590 release_firmware(pHddCtx->nv);
7591 pHddCtx->nv = NULL;
7592 }
7593 else
7594 status = VOS_STATUS_E_FAILURE;
7595
7596 }
7597
7598 EXIT();
7599 return status;
7600}
7601
7602/**---------------------------------------------------------------------------
7603
7604 \brief hdd_request_firmware() -
7605
7606 This function reads the firmware file using the request firmware
7607 API and returns the the firmware data and the firmware file size.
7608
7609 \param - pfileName - Pointer to the file name.
7610 - pCtx - Pointer to the adapter .
7611 - ppfw_data - Pointer to the pointer of the firmware data.
7612 - pSize - Pointer to the file size.
7613
7614 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7615
7616 --------------------------------------------------------------------------*/
7617
7618
7619VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7620{
7621 int status;
7622 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7623 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7624 ENTER();
7625
7626 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7627
7628 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7629
7630 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7631 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7632 __func__, pfileName);
7633 retval = VOS_STATUS_E_FAILURE;
7634 }
7635
7636 else {
7637 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7638 *pSize = pHddCtx->fw->size;
7639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7640 __func__, *pSize);
7641 }
7642 }
7643 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7644
7645 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7646
7647 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7648 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7649 __func__, pfileName);
7650 retval = VOS_STATUS_E_FAILURE;
7651 }
7652
7653 else {
7654 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7655 *pSize = pHddCtx->nv->size;
7656 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7657 __func__, *pSize);
7658 }
7659 }
7660
7661 EXIT();
7662 return retval;
7663}
7664/**---------------------------------------------------------------------------
7665 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7666
7667 This is the function invoked by SME to inform the result of a full power
7668 request issued by HDD
7669
7670 \param - callbackcontext - Pointer to cookie
7671 status - result of request
7672
7673 \return - None
7674
7675--------------------------------------------------------------------------*/
7676void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7677{
7678 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7679
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007680 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 if(&pHddCtx->full_pwr_comp_var)
7682 {
7683 complete(&pHddCtx->full_pwr_comp_var);
7684 }
7685}
7686
Abhishek Singh00b71972016-01-07 10:51:04 +05307687#ifdef WLAN_FEATURE_RMC
7688static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7689{
7690 int payload_len;
7691 struct sk_buff *skb;
7692 struct nlmsghdr *nlh;
7693 v_U8_t *data;
7694
7695 payload_len = ETH_ALEN;
7696
7697 if (0 == cesium_pid)
7698 {
7699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7700 __func__);
7701 return;
7702 }
7703
7704 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7705 {
7706 hddLog(VOS_TRACE_LEVEL_ERROR,
7707 "%s: nlmsg_new() failed for msg size[%d]",
7708 __func__, NLMSG_SPACE(payload_len));
7709 return;
7710 }
7711
7712 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7713
7714 if (NULL == nlh)
7715 {
7716 hddLog(VOS_TRACE_LEVEL_ERROR,
7717 "%s: nlmsg_put() failed for msg size[%d]",
7718 __func__, NLMSG_SPACE(payload_len));
7719
7720 kfree_skb(skb);
7721 return;
7722 }
7723
7724 data = nlmsg_data(nlh);
7725 memcpy(data, MacAddr, ETH_ALEN);
7726
7727 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7728 {
7729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7730 __func__, NLMSG_SPACE(payload_len));
7731 }
7732
7733 return;
7734}
7735
7736/**---------------------------------------------------------------------------
7737 \brief hdd_ParseuserParams - return a pointer to the next argument
7738
7739 \return - status
7740
7741--------------------------------------------------------------------------*/
7742static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7743{
7744 tANI_U8 *pVal;
7745
7746 pVal = strchr(pValue, ' ');
7747
7748 if (NULL == pVal)
7749 {
7750 /* no argument remains */
7751 return -EINVAL;
7752 }
7753 else if (SPACE_ASCII_VALUE != *pVal)
7754 {
7755 /* no space after the current argument */
7756 return -EINVAL;
7757 }
7758
7759 pVal++;
7760
7761 /* remove empty spaces */
7762 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7763 {
7764 pVal++;
7765 }
7766
7767 /* no argument followed by spaces */
7768 if ('\0' == *pVal)
7769 {
7770 return -EINVAL;
7771 }
7772
7773 *ppArg = pVal;
7774
7775 return 0;
7776}
7777
7778/**----------------------------------------------------------------------------
7779 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7780
7781 \return - status
7782
7783------------------------------------------------------------------------------*/
7784static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7785 tANI_U8 *tx_fail_count,
7786 tANI_U16 *pid)
7787{
7788 tANI_U8 *param = NULL;
7789 int ret;
7790
7791 ret = hdd_ParseUserParams(pValue, &param);
7792
7793 if (0 == ret && NULL != param)
7794 {
7795 if (1 != sscanf(param, "%hhu", tx_fail_count))
7796 {
7797 ret = -EINVAL;
7798 goto done;
7799 }
7800 }
7801 else
7802 {
7803 goto done;
7804 }
7805
7806 if (0 == *tx_fail_count)
7807 {
7808 *pid = 0;
7809 goto done;
7810 }
7811
7812 pValue = param;
7813 pValue++;
7814
7815 ret = hdd_ParseUserParams(pValue, &param);
7816
7817 if (0 == ret)
7818 {
7819 if (1 != sscanf(param, "%hu", pid))
7820 {
7821 ret = -EINVAL;
7822 goto done;
7823 }
7824 }
7825 else
7826 {
7827 goto done;
7828 }
7829
7830done:
7831 return ret;
7832}
7833
7834static int hdd_open_cesium_nl_sock()
7835{
7836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7837 struct netlink_kernel_cfg cfg = {
7838 .groups = WLAN_NLINK_MCAST_GRP_ID,
7839 .input = NULL
7840 };
7841#endif
7842 int ret = 0;
7843
7844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7845 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7847 THIS_MODULE,
7848#endif
7849 &cfg);
7850#else
7851 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7852 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7853#endif
7854
7855 if (cesium_nl_srv_sock == NULL)
7856 {
7857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7858 "NLINK: cesium netlink_kernel_create failed");
7859 ret = -ECONNREFUSED;
7860 }
7861
7862 return ret;
7863}
7864
7865static void hdd_close_cesium_nl_sock()
7866{
7867 if (NULL != cesium_nl_srv_sock)
7868 {
7869 netlink_kernel_release(cesium_nl_srv_sock);
7870 cesium_nl_srv_sock = NULL;
7871 }
7872}
7873#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007874/**---------------------------------------------------------------------------
7875
7876 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7877
7878 This is the function invoked by SME to inform the result of BMPS
7879 request issued by HDD
7880
7881 \param - callbackcontext - Pointer to cookie
7882 status - result of request
7883
7884 \return - None
7885
7886--------------------------------------------------------------------------*/
7887void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7888{
7889
7890 struct completion *completion_var = (struct completion*) callbackContext;
7891
Arif Hussain6d2a3322013-11-17 19:50:10 -08007892 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 if(completion_var != NULL)
7894 {
7895 complete(completion_var);
7896 }
7897}
7898
7899/**---------------------------------------------------------------------------
7900
7901 \brief hdd_get_cfg_file_size() -
7902
7903 This function reads the configuration file using the request firmware
7904 API and returns the configuration file size.
7905
7906 \param - pCtx - Pointer to the adapter .
7907 - pFileName - Pointer to the file name.
7908 - pBufSize - Pointer to the buffer size.
7909
7910 \return - 0 for success, non zero for failure
7911
7912 --------------------------------------------------------------------------*/
7913
7914VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7915{
7916 int status;
7917 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7918
7919 ENTER();
7920
7921 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7922
7923 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7924 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7925 status = VOS_STATUS_E_FAILURE;
7926 }
7927 else {
7928 *pBufSize = pHddCtx->fw->size;
7929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7930 release_firmware(pHddCtx->fw);
7931 pHddCtx->fw = NULL;
7932 }
7933
7934 EXIT();
7935 return VOS_STATUS_SUCCESS;
7936}
7937
7938/**---------------------------------------------------------------------------
7939
7940 \brief hdd_read_cfg_file() -
7941
7942 This function reads the configuration file using the request firmware
7943 API and returns the cfg data and the buffer size of the configuration file.
7944
7945 \param - pCtx - Pointer to the adapter .
7946 - pFileName - Pointer to the file name.
7947 - pBuffer - Pointer to the data buffer.
7948 - pBufSize - Pointer to the buffer size.
7949
7950 \return - 0 for success, non zero for failure
7951
7952 --------------------------------------------------------------------------*/
7953
7954VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7955 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7956{
7957 int status;
7958 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7959
7960 ENTER();
7961
7962 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7963
7964 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7965 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7966 return VOS_STATUS_E_FAILURE;
7967 }
7968 else {
7969 if(*pBufSize != pHddCtx->fw->size) {
7970 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7971 "file size", __func__);
7972 release_firmware(pHddCtx->fw);
7973 pHddCtx->fw = NULL;
7974 return VOS_STATUS_E_FAILURE;
7975 }
7976 else {
7977 if(pBuffer) {
7978 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7979 }
7980 release_firmware(pHddCtx->fw);
7981 pHddCtx->fw = NULL;
7982 }
7983 }
7984
7985 EXIT();
7986
7987 return VOS_STATUS_SUCCESS;
7988}
7989
7990/**---------------------------------------------------------------------------
7991
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307992 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007993
7994 This function sets the user specified mac address using
7995 the command ifconfig wlanX hw ether <mac adress>.
7996
7997 \param - dev - Pointer to the net device.
7998 - addr - Pointer to the sockaddr.
7999 \return - 0 for success, non zero for failure
8000
8001 --------------------------------------------------------------------------*/
8002
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308003static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008004{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308005 hdd_adapter_t *pAdapter;
8006 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 struct sockaddr *psta_mac_addr = addr;
8008 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308009 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008010
8011 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308012 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8013 if (NULL == pAdapter)
8014 {
8015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8016 "%s: Adapter is NULL",__func__);
8017 return -EINVAL;
8018 }
8019 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8020 ret = wlan_hdd_validate_context(pHddCtx);
8021 if (0 != ret)
8022 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308023 return ret;
8024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008025
8026 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8028
8029 EXIT();
8030 return halStatus;
8031}
8032
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308033/**---------------------------------------------------------------------------
8034
8035 \brief hdd_set_mac_address() -
8036
8037 Wrapper function to protect __hdd_set_mac_address() function from ssr
8038
8039 \param - dev - Pointer to the net device.
8040 - addr - Pointer to the sockaddr.
8041 \return - 0 for success, non zero for failure
8042
8043 --------------------------------------------------------------------------*/
8044static int hdd_set_mac_address(struct net_device *dev, void *addr)
8045{
8046 int ret;
8047
8048 vos_ssr_protect(__func__);
8049 ret = __hdd_set_mac_address(dev, addr);
8050 vos_ssr_unprotect(__func__);
8051
8052 return ret;
8053}
8054
Jeff Johnson295189b2012-06-20 16:38:30 -07008055tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8056{
8057 int i;
8058 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8059 {
Abhishek Singheb183782014-02-06 13:37:21 +05308060 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 break;
8062 }
8063
8064 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8065 return NULL;
8066
8067 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8068 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8069}
8070
8071void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8072{
8073 int i;
8074 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8075 {
8076 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8077 {
8078 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8079 break;
8080 }
8081 }
8082 return;
8083}
8084
8085#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8086 static struct net_device_ops wlan_drv_ops = {
8087 .ndo_open = hdd_open,
8088 .ndo_stop = hdd_stop,
8089 .ndo_uninit = hdd_uninit,
8090 .ndo_start_xmit = hdd_hard_start_xmit,
8091 .ndo_tx_timeout = hdd_tx_timeout,
8092 .ndo_get_stats = hdd_stats,
8093 .ndo_do_ioctl = hdd_ioctl,
8094 .ndo_set_mac_address = hdd_set_mac_address,
8095 .ndo_select_queue = hdd_select_queue,
8096#ifdef WLAN_FEATURE_PACKET_FILTERING
8097#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8098 .ndo_set_rx_mode = hdd_set_multicast_list,
8099#else
8100 .ndo_set_multicast_list = hdd_set_multicast_list,
8101#endif //LINUX_VERSION_CODE
8102#endif
8103 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 static struct net_device_ops wlan_mon_drv_ops = {
8105 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308106 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 .ndo_uninit = hdd_uninit,
8108 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8109 .ndo_tx_timeout = hdd_tx_timeout,
8110 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308111 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 .ndo_set_mac_address = hdd_set_mac_address,
8113 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308114
Jeff Johnson295189b2012-06-20 16:38:30 -07008115#endif
8116
8117void hdd_set_station_ops( struct net_device *pWlanDev )
8118{
8119#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 pWlanDev->netdev_ops = &wlan_drv_ops;
8121#else
8122 pWlanDev->open = hdd_open;
8123 pWlanDev->stop = hdd_stop;
8124 pWlanDev->uninit = hdd_uninit;
8125 pWlanDev->hard_start_xmit = NULL;
8126 pWlanDev->tx_timeout = hdd_tx_timeout;
8127 pWlanDev->get_stats = hdd_stats;
8128 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 pWlanDev->set_mac_address = hdd_set_mac_address;
8130#endif
8131}
8132
Katya Nigam1fd24402015-02-16 14:52:19 +05308133void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
8134{
8135 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8136 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
8137 #else
8138 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
8139 #endif
8140}
8141
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008142static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07008143{
8144 struct net_device *pWlanDev = NULL;
8145 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 /*
8147 * cfg80211 initialization and registration....
8148 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05308149 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
8150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
8151 NET_NAME_UNKNOWN,
8152#endif
8153 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07008154 if(pWlanDev != NULL)
8155 {
8156
8157 //Save the pointer to the net_device in the HDD adapter
8158 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
8159
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
8161
8162 pAdapter->dev = pWlanDev;
8163 pAdapter->pHddCtx = pHddCtx;
8164 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05308165 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07008166
Rajeev79dbe4c2013-10-05 11:03:42 +05308167#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05308168 pAdapter->pBatchScanRsp = NULL;
8169 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07008170 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08008171 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05308172 mutex_init(&pAdapter->hdd_batch_scan_lock);
8173#endif
8174
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 pAdapter->isLinkUpSvcNeeded = FALSE;
8176 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
8177 //Init the net_device structure
8178 strlcpy(pWlanDev->name, name, IFNAMSIZ);
8179
8180 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
8181 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
8182 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
8183 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
8184
8185 hdd_set_station_ops( pAdapter->dev );
8186
8187 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
8189 pAdapter->wdev.wiphy = pHddCtx->wiphy;
8190 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 /* set pWlanDev's parent to underlying device */
8192 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07008193
8194 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008195 }
8196
8197 return pAdapter;
8198}
8199
8200VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
8201{
8202 struct net_device *pWlanDev = pAdapter->dev;
8203 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8204 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8205 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8206
8207 if( rtnl_lock_held )
8208 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08008209 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
8211 {
8212 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
8213 return VOS_STATUS_E_FAILURE;
8214 }
8215 }
8216 if (register_netdevice(pWlanDev))
8217 {
8218 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
8219 return VOS_STATUS_E_FAILURE;
8220 }
8221 }
8222 else
8223 {
8224 if(register_netdev(pWlanDev))
8225 {
8226 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
8227 return VOS_STATUS_E_FAILURE;
8228 }
8229 }
8230 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
8231
8232 return VOS_STATUS_SUCCESS;
8233}
8234
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008235static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07008236{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008237 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008238
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008239 if (NULL == pAdapter)
8240 {
8241 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
8242 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008244
8245 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8246 {
8247 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
8248 return eHAL_STATUS_NOT_INITIALIZED;
8249 }
8250
8251 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
8252
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008253#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008254 /* need to make sure all of our scheduled work has completed.
8255 * This callback is called from MC thread context, so it is safe to
8256 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008257 *
8258 * Even though this is called from MC thread context, if there is a faulty
8259 * work item in the system, that can hang this call forever. So flushing
8260 * this global work queue is not safe; and now we make sure that
8261 * individual work queues are stopped correctly. But the cancel work queue
8262 * is a GPL only API, so the proprietary version of the driver would still
8263 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008264 */
8265 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008266#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008267
8268 /* We can be blocked while waiting for scheduled work to be
8269 * flushed, and the adapter structure can potentially be freed, in
8270 * which case the magic will have been reset. So make sure the
8271 * magic is still good, and hence the adapter structure is still
8272 * valid, before signaling completion */
8273 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8274 {
8275 complete(&pAdapter->session_close_comp_var);
8276 }
8277
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 return eHAL_STATUS_SUCCESS;
8279}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308280/**
8281 * hdd_close_tx_queues() - close tx queues
8282 * @hdd_ctx: hdd global context
8283 *
8284 * Return: None
8285 */
8286static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8287{
8288 VOS_STATUS status;
8289 hdd_adapter_t *adapter;
8290 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8291 /* Not validating hdd_ctx as it's already done by the caller */
8292 ENTER();
8293 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8294 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8295 adapter = adapter_node->pAdapter;
8296 if (adapter && adapter->dev) {
8297 netif_tx_disable (adapter->dev);
8298 netif_carrier_off(adapter->dev);
8299 }
8300 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8301 &next_adapter);
8302 adapter_node = next_adapter;
8303 }
8304 EXIT();
8305}
Jeff Johnson295189b2012-06-20 16:38:30 -07008306
8307VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8308{
8309 struct net_device *pWlanDev = pAdapter->dev;
8310 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8311 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8312 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8313 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308314 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008315
Nirav Shah7e3c8132015-06-22 23:51:42 +05308316 spin_lock_init( &pAdapter->sta_hash_lock);
8317 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8318
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008320 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 //Open a SME session for future operation
8322 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008323 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8325 {
8326 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008327 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 halStatus, halStatus );
8329 status = VOS_STATUS_E_FAILURE;
8330 goto error_sme_open;
8331 }
8332
8333 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308334 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 &pAdapter->session_open_comp_var,
8336 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308337 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 {
8339 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308340 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 status = VOS_STATUS_E_FAILURE;
8342 goto error_sme_open;
8343 }
8344
8345 // Register wireless extensions
8346 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8347 {
8348 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008349 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 halStatus, halStatus );
8351 status = VOS_STATUS_E_FAILURE;
8352 goto error_register_wext;
8353 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308354
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308356 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8357 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8358 #else
8359 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8360 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008361
8362 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308363 hddLog(VOS_TRACE_LEVEL_INFO,
8364 "%s: Set HDD connState to eConnectionState_NotConnected",
8365 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8367
8368 //Set the default operation channel
8369 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8370
8371 /* Make the default Auth Type as OPEN*/
8372 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8373
8374 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8375 {
8376 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008377 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 status, status );
8379 goto error_init_txrx;
8380 }
8381
8382 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8383
8384 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8385 {
8386 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008387 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 status, status );
8389 goto error_wmm_init;
8390 }
8391
8392 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8393
8394 return VOS_STATUS_SUCCESS;
8395
8396error_wmm_init:
8397 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8398 hdd_deinit_tx_rx(pAdapter);
8399error_init_txrx:
8400 hdd_UnregisterWext(pWlanDev);
8401error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008402 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 {
8404 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008405 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308406 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008407 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308409 unsigned long rc;
8410
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308412 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008414 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308415 if (rc <= 0)
8416 hddLog(VOS_TRACE_LEVEL_ERROR,
8417 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 }
8419}
8420error_sme_open:
8421 return status;
8422}
8423
Jeff Johnson295189b2012-06-20 16:38:30 -07008424void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8425{
8426 hdd_cfg80211_state_t *cfgState;
8427
8428 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8429
8430 if( NULL != cfgState->buf )
8431 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308432 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8434 rc = wait_for_completion_interruptible_timeout(
8435 &pAdapter->tx_action_cnf_event,
8436 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308437 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8440 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8441 , __func__, rc);
8442
8443 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8444 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 }
8446 }
8447 return;
8448}
Jeff Johnson295189b2012-06-20 16:38:30 -07008449
c_hpothu002231a2015-02-05 14:58:51 +05308450void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008451{
8452 ENTER();
8453 switch ( pAdapter->device_mode )
8454 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308455 case WLAN_HDD_IBSS:
8456 {
8457 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8458 {
8459 hdd_ibss_deinit_tx_rx( pAdapter );
8460 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8461 }
8462 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 case WLAN_HDD_INFRA_STATION:
8464 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008465 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 {
8467 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8468 {
8469 hdd_deinit_tx_rx( pAdapter );
8470 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8471 }
8472
8473 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8474 {
8475 hdd_wmm_adapter_close( pAdapter );
8476 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8477 }
8478
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 break;
8481 }
8482
8483 case WLAN_HDD_SOFTAP:
8484 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308486
8487 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8488 {
8489 hdd_wmm_adapter_close( pAdapter );
8490 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8491 }
8492
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008494
c_hpothu002231a2015-02-05 14:58:51 +05308495 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05308496 /* set con_mode to STA only when no SAP concurrency mode */
8497 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
8498 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 break;
8500 }
8501
8502 case WLAN_HDD_MONITOR:
8503 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8505 {
8506 hdd_deinit_tx_rx( pAdapter );
8507 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 break;
8510 }
8511
8512
8513 default:
8514 break;
8515 }
8516
8517 EXIT();
8518}
8519
8520void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8521{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008522 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308523
8524 ENTER();
8525 if (NULL == pAdapter)
8526 {
8527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8528 "%s: HDD adapter is Null", __func__);
8529 return;
8530 }
8531
8532 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008533
Rajeev79dbe4c2013-10-05 11:03:42 +05308534#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308535 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8536 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008537 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308538 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8539 )
8540 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008541 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308542 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008543 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8544 {
8545 hdd_deinit_batch_scan(pAdapter);
8546 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308547 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008548 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308549#endif
8550
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8552 if( rtnl_held )
8553 {
8554 unregister_netdevice(pWlanDev);
8555 }
8556 else
8557 {
8558 unregister_netdev(pWlanDev);
8559 }
8560 // note that the pAdapter is no longer valid at this point
8561 // since the memory has been reclaimed
8562 }
8563
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308564 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008565}
8566
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008567void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8568{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308569 VOS_STATUS status;
8570 hdd_adapter_t *pAdapter = NULL;
8571 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008572
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308573 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008574
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308575 /*loop through all adapters.*/
8576 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008577 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308578 pAdapter = pAdapterNode->pAdapter;
8579 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8580 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008581
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308582 { // we skip this registration for modes other than STA and P2P client modes.
8583 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8584 pAdapterNode = pNext;
8585 continue;
8586 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008587
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308588 //Apply Dynamic DTIM For P2P
8589 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8590 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8591 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8592 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8593 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8594 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8595 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8596 (eConnectionState_Associated ==
8597 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8598 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8599 {
8600 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008601
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308602 powerRequest.uIgnoreDTIM = 1;
8603 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8604
8605 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8606 {
8607 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8608 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8609 }
8610 else
8611 {
8612 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8613 }
8614
8615 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8616 * specified during Enter/Exit BMPS when LCD off*/
8617 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8618 NULL, eANI_BOOLEAN_FALSE);
8619 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8620 NULL, eANI_BOOLEAN_FALSE);
8621
8622 /* switch to the DTIM specified in cfg.ini */
8623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308624 "Switch to DTIM %d Listen interval %d",
8625 powerRequest.uDTIMPeriod,
8626 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308627 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8628 break;
8629
8630 }
8631
8632 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8633 pAdapterNode = pNext;
8634 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008635}
8636
8637void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8638{
8639 /*Switch back to DTIM 1*/
8640 tSirSetPowerParamsReq powerRequest = { 0 };
8641
8642 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8643 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008644 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008645
8646 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8647 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8648 NULL, eANI_BOOLEAN_FALSE);
8649 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8650 NULL, eANI_BOOLEAN_FALSE);
8651
8652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8653 "Switch to DTIM%d",powerRequest.uListenInterval);
8654 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8655
8656}
8657
Jeff Johnson295189b2012-06-20 16:38:30 -07008658VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8659{
8660 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308661 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8662 {
8663 hddLog( LOGE, FL("Wlan Unload in progress"));
8664 return VOS_STATUS_E_PERM;
8665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8667 {
8668 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8669 }
8670
8671 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8672 {
8673 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8674 }
8675
8676 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8677 {
8678 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8679 }
8680
8681 return status;
8682}
8683
8684VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8685{
8686 hdd_adapter_t *pAdapter = NULL;
8687 eHalStatus halStatus;
8688 VOS_STATUS status = VOS_STATUS_E_INVAL;
8689 v_BOOL_t disableBmps = FALSE;
8690 v_BOOL_t disableImps = FALSE;
8691
8692 switch(session_type)
8693 {
8694 case WLAN_HDD_INFRA_STATION:
8695 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 case WLAN_HDD_P2P_CLIENT:
8697 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 //Exit BMPS -> Is Sta/P2P Client is already connected
8699 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8700 if((NULL != pAdapter)&&
8701 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8702 {
8703 disableBmps = TRUE;
8704 }
8705
8706 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8707 if((NULL != pAdapter)&&
8708 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8709 {
8710 disableBmps = TRUE;
8711 }
8712
8713 //Exit both Bmps and Imps incase of Go/SAP Mode
8714 if((WLAN_HDD_SOFTAP == session_type) ||
8715 (WLAN_HDD_P2P_GO == session_type))
8716 {
8717 disableBmps = TRUE;
8718 disableImps = TRUE;
8719 }
8720
8721 if(TRUE == disableImps)
8722 {
8723 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8724 {
8725 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8726 }
8727 }
8728
8729 if(TRUE == disableBmps)
8730 {
8731 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8732 {
8733 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8734
8735 if(eHAL_STATUS_SUCCESS != halStatus)
8736 {
8737 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008738 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 VOS_ASSERT(0);
8740 return status;
8741 }
8742 }
8743
8744 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8745 {
8746 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8747
8748 if(eHAL_STATUS_SUCCESS != halStatus)
8749 {
8750 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008751 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 VOS_ASSERT(0);
8753 return status;
8754 }
8755 }
8756 }
8757
8758 if((TRUE == disableBmps) ||
8759 (TRUE == disableImps))
8760 {
8761 /* Now, get the chip into Full Power now */
8762 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8763 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8764 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8765
8766 if(halStatus != eHAL_STATUS_SUCCESS)
8767 {
8768 if(halStatus == eHAL_STATUS_PMC_PENDING)
8769 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308770 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308772 ret = wait_for_completion_interruptible_timeout(
8773 &pHddCtx->full_pwr_comp_var,
8774 msecs_to_jiffies(1000));
8775 if (ret <= 0)
8776 {
8777 hddLog(VOS_TRACE_LEVEL_ERROR,
8778 "%s: wait on full_pwr_comp_var failed %ld",
8779 __func__, ret);
8780 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 }
8782 else
8783 {
8784 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008785 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 VOS_ASSERT(0);
8787 return status;
8788 }
8789 }
8790
8791 status = VOS_STATUS_SUCCESS;
8792 }
8793
8794 break;
8795 }
8796 return status;
8797}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308798
8799void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8800{
8801 if (magic == NULL || cmpVar == NULL) {
8802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07008803 FL("invalid arguments %pK %pK"), magic, cmpVar);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308804 return;
8805 }
8806 if (*magic != MON_MODE_MSG_MAGIC) {
8807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8808 FL("maic: %x"), *magic);
8809 return;
8810 }
8811
8812 complete(cmpVar);
8813 return;
8814}
8815
Katya Nigame7b69a82015-04-28 15:24:06 +05308816void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8817 {
8818 hdd_mon_ctx_t *pMonCtx = NULL;
8819 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8820
8821 pMonCtx->state = 0;
8822 pMonCtx->ChannelNo = 1;
8823 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308824 pMonCtx->crcCheckEnabled = 1;
8825 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8826 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308827 pMonCtx->numOfMacFilters = 0;
8828 }
8829
Jeff Johnson295189b2012-06-20 16:38:30 -07008830
8831hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008832 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 tANI_U8 rtnl_held )
8834{
8835 hdd_adapter_t *pAdapter = NULL;
8836 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8837 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8838 VOS_STATUS exitbmpsStatus;
8839
Arif Hussain6d2a3322013-11-17 19:50:10 -08008840 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008841
Nirav Shah436658f2014-02-28 17:05:45 +05308842 if(macAddr == NULL)
8843 {
8844 /* Not received valid macAddr */
8845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8846 "%s:Unable to add virtual intf: Not able to get"
8847 "valid mac address",__func__);
8848 return NULL;
8849 }
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 //Disable BMPS incase of Concurrency
8852 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8853
8854 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8855 {
8856 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308857 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 VOS_ASSERT(0);
8859 return NULL;
8860 }
8861
8862 switch(session_type)
8863 {
8864 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008866 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 {
8868 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8869
8870 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308871 {
8872 hddLog(VOS_TRACE_LEVEL_FATAL,
8873 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308875 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308877#ifdef FEATURE_WLAN_TDLS
8878 /* A Mutex Lock is introduced while changing/initializing the mode to
8879 * protect the concurrent access for the Adapters by TDLS module.
8880 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308881 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308882#endif
8883
Jeff Johnsone7245742012-09-05 17:12:55 -07008884 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8885 NL80211_IFTYPE_P2P_CLIENT:
8886 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008887
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308889#ifdef FEATURE_WLAN_TDLS
8890 mutex_unlock(&pHddCtx->tdls_lock);
8891#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308892
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308893 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308894 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 if( VOS_STATUS_SUCCESS != status )
8896 goto err_free_netdev;
8897
8898 status = hdd_register_interface( pAdapter, rtnl_held );
8899 if( VOS_STATUS_SUCCESS != status )
8900 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308901#ifdef FEATURE_WLAN_TDLS
8902 mutex_lock(&pHddCtx->tdls_lock);
8903#endif
c_hpothu002231a2015-02-05 14:58:51 +05308904 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308905#ifdef FEATURE_WLAN_TDLS
8906 mutex_unlock(&pHddCtx->tdls_lock);
8907#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 goto err_free_netdev;
8909 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308910
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308911 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308912 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308913
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308914#ifdef WLAN_NS_OFFLOAD
8915 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308916 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308917#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308919 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 netif_tx_disable(pAdapter->dev);
8921 //netif_tx_disable(pWlanDev);
8922 netif_carrier_off(pAdapter->dev);
8923
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308924 if (WLAN_HDD_P2P_CLIENT == session_type ||
8925 WLAN_HDD_P2P_DEVICE == session_type)
8926 {
8927 /* Initialize the work queue to defer the
8928 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308929 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308930 hdd_p2p_roc_work_queue);
8931 }
8932
Jeff Johnson295189b2012-06-20 16:38:30 -07008933 break;
8934 }
8935
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 case WLAN_HDD_SOFTAP:
8938 {
8939 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8940 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308941 {
8942 hddLog(VOS_TRACE_LEVEL_FATAL,
8943 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008946
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8948 NL80211_IFTYPE_AP:
8949 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 pAdapter->device_mode = session_type;
8951
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308952 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05308953 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 if( VOS_STATUS_SUCCESS != status )
8955 goto err_free_netdev;
8956
Nirav Shah7e3c8132015-06-22 23:51:42 +05308957 status = hdd_sta_id_hash_attach(pAdapter);
8958 if (VOS_STATUS_SUCCESS != status)
8959 {
8960 hddLog(VOS_TRACE_LEVEL_FATAL,
8961 FL("failed to attach hash for session %d"), session_type);
8962 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8963 goto err_free_netdev;
8964 }
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 status = hdd_register_hostapd( pAdapter, rtnl_held );
8967 if( VOS_STATUS_SUCCESS != status )
8968 {
c_hpothu002231a2015-02-05 14:58:51 +05308969 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 goto err_free_netdev;
8971 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308972 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 netif_tx_disable(pAdapter->dev);
8974 netif_carrier_off(pAdapter->dev);
8975
8976 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308977
8978 if (WLAN_HDD_P2P_GO == session_type)
8979 {
8980 /* Initialize the work queue to
8981 * defer the back to back RoC request */
8982 INIT_DELAYED_WORK(&pAdapter->roc_work,
8983 hdd_p2p_roc_work_queue);
8984 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308985
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 break;
8987 }
8988 case WLAN_HDD_MONITOR:
8989 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8991 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308992 {
8993 hddLog(VOS_TRACE_LEVEL_FATAL,
8994 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008997
Katya Nigame7b69a82015-04-28 15:24:06 +05308998 // Register wireless extensions
8999 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9000 {
9001 hddLog(VOS_TRACE_LEVEL_FATAL,
9002 "hdd_register_wext() failed with status code %08d [x%08x]",
9003 status, status );
9004 status = VOS_STATUS_E_FAILURE;
9005 }
9006
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9008 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009009#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9010 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9011#else
9012 pAdapter->dev->open = hdd_mon_open;
9013 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309014 pAdapter->dev->stop = hdd_mon_stop;
9015 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309017 status = hdd_register_interface( pAdapter, rtnl_held );
9018 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309019 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 hdd_init_tx_rx( pAdapter );
9021 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05309022 //Stop the Interface TX queue.
9023 netif_tx_disable(pAdapter->dev);
9024 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009025 }
9026 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009027 case WLAN_HDD_FTM:
9028 {
9029 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9030
9031 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309032 {
9033 hddLog(VOS_TRACE_LEVEL_FATAL,
9034 FL("failed to allocate adapter for session %d"), session_type);
9035 return NULL;
9036 }
9037
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9039 * message while loading driver in FTM mode. */
9040 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9041 pAdapter->device_mode = session_type;
9042 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309043
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309044 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309045 hdd_init_tx_rx( pAdapter );
9046
9047 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309049 netif_tx_disable(pAdapter->dev);
9050 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 }
9052 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 default:
9054 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309055 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9056 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 VOS_ASSERT(0);
9058 return NULL;
9059 }
9060 }
9061
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 if( VOS_STATUS_SUCCESS == status )
9063 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309064 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9066 if( NULL == pHddAdapterNode )
9067 {
9068 status = VOS_STATUS_E_NOMEM;
9069 }
9070 else
9071 {
9072 pHddAdapterNode->pAdapter = pAdapter;
9073 status = hdd_add_adapter_back ( pHddCtx,
9074 pHddAdapterNode );
9075 }
9076 }
9077
9078 if( VOS_STATUS_SUCCESS != status )
9079 {
9080 if( NULL != pAdapter )
9081 {
9082 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9083 pAdapter = NULL;
9084 }
9085 if( NULL != pHddAdapterNode )
9086 {
9087 vos_mem_free( pHddAdapterNode );
9088 }
9089
9090 goto resume_bmps;
9091 }
9092
9093 if(VOS_STATUS_SUCCESS == status)
9094 {
9095 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07009096 //Initialize the WoWL service
9097 if(!hdd_init_wowl(pAdapter))
9098 {
9099 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
9100 goto err_free_netdev;
9101 }
Manjeet Singh3ed79242017-01-11 19:04:32 +05309102 //Initialize the TSF capture data
9103 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 return pAdapter;
9106
9107err_free_netdev:
9108 free_netdev(pAdapter->dev);
9109 wlan_hdd_release_intf_addr( pHddCtx,
9110 pAdapter->macAddressCurrent.bytes );
9111
9112resume_bmps:
9113 //If bmps disabled enable it
9114 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
9115 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309116 if (pHddCtx->hdd_wlan_suspended)
9117 {
9118 hdd_set_pwrparams(pHddCtx);
9119 }
9120 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 }
9122 return NULL;
9123}
9124
9125VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
9126 tANI_U8 rtnl_held )
9127{
9128 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
9129 VOS_STATUS status;
9130
9131 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
9132 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309133 {
9134 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
9135 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309137 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009138
9139 while ( pCurrent->pAdapter != pAdapter )
9140 {
9141 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
9142 if( VOS_STATUS_SUCCESS != status )
9143 break;
9144
9145 pCurrent = pNext;
9146 }
9147 pAdapterNode = pCurrent;
9148 if( VOS_STATUS_SUCCESS == status )
9149 {
9150 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
9151 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309152
9153#ifdef FEATURE_WLAN_TDLS
9154
9155 /* A Mutex Lock is introduced while changing/initializing the mode to
9156 * protect the concurrent access for the Adapters by TDLS module.
9157 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309158 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309159#endif
9160
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 hdd_remove_adapter( pHddCtx, pAdapterNode );
9162 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009163 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009164
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309165#ifdef FEATURE_WLAN_TDLS
9166 mutex_unlock(&pHddCtx->tdls_lock);
9167#endif
9168
Jeff Johnson295189b2012-06-20 16:38:30 -07009169
9170 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05309171 if ((!vos_concurrent_open_sessions_running()) &&
9172 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
9173 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309175 if (pHddCtx->hdd_wlan_suspended)
9176 {
9177 hdd_set_pwrparams(pHddCtx);
9178 }
9179 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009180 }
9181
9182 return VOS_STATUS_SUCCESS;
9183 }
9184
9185 return VOS_STATUS_E_FAILURE;
9186}
9187
9188VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
9189{
9190 hdd_adapter_list_node_t *pHddAdapterNode;
9191 VOS_STATUS status;
9192
9193 ENTER();
9194
9195 do
9196 {
9197 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
9198 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
9199 {
9200 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
9201 vos_mem_free( pHddAdapterNode );
9202 }
9203 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
9204
9205 EXIT();
9206
9207 return VOS_STATUS_SUCCESS;
9208}
9209
9210void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
9211{
9212 v_U8_t addIE[1] = {0};
9213
9214 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9215 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
9216 eANI_BOOLEAN_FALSE) )
9217 {
9218 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009219 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 }
9221
9222 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9223 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9224 eANI_BOOLEAN_FALSE) )
9225 {
9226 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009227 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 }
9229
9230 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9231 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9232 eANI_BOOLEAN_FALSE) )
9233 {
9234 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009235 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 }
9237}
9238
Anurag Chouhan83026002016-12-13 22:46:21 +05309239VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
9240{
9241#ifdef DHCP_SERVER_OFFLOAD
9242 vos_event_destroy(&adapter->dhcp_status.vos_event);
9243#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309244#ifdef MDNS_OFFLOAD
9245 vos_event_destroy(&adapter->mdns_status.vos_event);
9246#endif
Anurag Chouhan83026002016-12-13 22:46:21 +05309247 return VOS_STATUS_SUCCESS;
9248}
9249
9250
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309251VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
9252 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07009253{
9254 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9255 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309256 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309258 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309259 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05309260 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009261
Anand N Sunkad26d71b92014-12-24 18:08:22 +05309262 if (pHddCtx->isLogpInProgress) {
9263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9264 "%s:LOGP in Progress. Ignore!!!",__func__);
9265 return VOS_STATUS_E_FAILURE;
9266 }
9267
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309269
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309270 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 switch(pAdapter->device_mode)
9272 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05309273 case WLAN_HDD_IBSS:
9274 if ( VOS_TRUE == bCloseSession )
9275 {
9276 status = hdd_sta_id_hash_detach(pAdapter);
9277 if (status != VOS_STATUS_SUCCESS)
9278 hddLog(VOS_TRACE_LEVEL_ERROR,
9279 FL("sta id hash detach failed"));
9280 }
9281
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 case WLAN_HDD_INFRA_STATION:
9283 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009284 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309285 {
9286 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309287#ifdef FEATURE_WLAN_TDLS
9288 mutex_lock(&pHddCtx->tdls_lock);
9289 wlan_hdd_tdls_exit(pAdapter, TRUE);
9290 mutex_unlock(&pHddCtx->tdls_lock);
9291#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309292 if( hdd_connIsConnected(pstation) ||
9293 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 {
Abhishek Singhe21a5212017-06-09 09:42:58 +05309295 /*
9296 * Indicate sme of disconnect so that in progress connection
9297 * or preauth can be aborted.
9298 */
9299 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
9300 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +05309301 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9303 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9304 pAdapter->sessionId,
9305 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9306 else
9307 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9308 pAdapter->sessionId,
9309 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309310 /* Success implies disconnect command got queued up successfully
9311 * Or cmd not queued as scan for SSID is in progress
9312 */
9313 if((eHAL_STATUS_SUCCESS == halStatus) ||
9314 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309316 ret = wait_for_completion_interruptible_timeout(
9317 &pAdapter->disconnect_comp_var,
9318 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309319 if (ret <= 0 &&
9320 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309321 {
9322 hddLog(VOS_TRACE_LEVEL_ERROR,
9323 "%s: wait on disconnect_comp_var failed %ld",
9324 __func__, ret);
9325 }
9326 }
9327 else
9328 {
9329 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9330 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 }
9332 memset(&wrqu, '\0', sizeof(wrqu));
9333 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9334 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9335 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9336 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309337 else if(pstation->conn_info.connState ==
9338 eConnectionState_Disconnecting)
9339 {
9340 ret = wait_for_completion_interruptible_timeout(
9341 &pAdapter->disconnect_comp_var,
9342 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9343 if (ret <= 0)
9344 {
9345 hddLog(VOS_TRACE_LEVEL_ERROR,
9346 FL("wait on disconnect_comp_var failed %ld"), ret);
9347 }
9348 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +05309349 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309351 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309353 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9354 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309355 {
9356 while (pAdapter->is_roc_inprogress)
9357 {
9358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9359 "%s: ROC in progress for session %d!!!",
9360 __func__, pAdapter->sessionId);
9361 // waiting for ROC to expire
9362 msleep(500);
9363 /* In GO present case , if retry exceeds 3,
9364 it means something went wrong. */
9365 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9366 {
9367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9368 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309369 if (eHAL_STATUS_SUCCESS !=
9370 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9371 pAdapter->sessionId ))
9372 {
9373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9374 FL("Failed to Cancel Remain on Channel"));
9375 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309376 wait_for_completion_interruptible_timeout(
9377 &pAdapter->cancel_rem_on_chan_var,
9378 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9379 break;
9380 }
9381 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309382 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309383 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309384#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309385 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309386#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309387
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309388 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309389
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309390 /* It is possible that the caller of this function does not
9391 * wish to close the session
9392 */
9393 if (VOS_TRUE == bCloseSession &&
9394 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 {
9396 INIT_COMPLETION(pAdapter->session_close_comp_var);
9397 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309398 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9399 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309401 unsigned long ret;
9402
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309404 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309405 &pAdapter->session_close_comp_var,
9406 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309407 if ( 0 >= ret)
9408 {
9409 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309410 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 }
9413 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309414 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 break;
9416
9417 case WLAN_HDD_SOFTAP:
9418 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309419 if ( VOS_TRUE == bCloseSession )
9420 {
9421 status = hdd_sta_id_hash_detach(pAdapter);
9422 if (status != VOS_STATUS_SUCCESS)
9423 hddLog(VOS_TRACE_LEVEL_ERROR,
9424 FL("sta id hash detach failed"));
9425 }
9426
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +05309428 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309429 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9430 while (pAdapter->is_roc_inprogress) {
9431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9432 "%s: ROC in progress for session %d!!!",
9433 __func__, pAdapter->sessionId);
9434 msleep(500);
9435 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9437 "%s: ROC completion is not received.!!!", __func__);
9438 WLANSAP_CancelRemainOnChannel(
9439 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9440 wait_for_completion_interruptible_timeout(
9441 &pAdapter->cancel_rem_on_chan_var,
9442 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9443 break;
9444 }
9445 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309446
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309447 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309448 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +05309449#ifdef SAP_AUTH_OFFLOAD
9450 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
9451 hdd_set_sap_auth_offload(pAdapter, FALSE);
9452#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 mutex_lock(&pHddCtx->sap_lock);
9454 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9455 {
9456 VOS_STATUS status;
9457 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9458
9459 //Stop Bss.
9460 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9461 if (VOS_IS_STATUS_SUCCESS(status))
9462 {
9463 hdd_hostapd_state_t *pHostapdState =
9464 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9465
9466 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9467
9468 if (!VOS_IS_STATUS_SUCCESS(status))
9469 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309470 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9471 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 }
9473 }
9474 else
9475 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009476 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 }
9478 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309479 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009480
9481 if (eHAL_STATUS_FAILURE ==
9482 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9483 0, NULL, eANI_BOOLEAN_FALSE))
9484 {
9485 hddLog(LOGE,
9486 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009487 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 }
9489
9490 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9491 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9492 eANI_BOOLEAN_FALSE) )
9493 {
9494 hddLog(LOGE,
9495 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9496 }
9497
9498 // Reset WNI_CFG_PROBE_RSP Flags
9499 wlan_hdd_reset_prob_rspies(pAdapter);
9500 kfree(pAdapter->sessionCtx.ap.beacon);
9501 pAdapter->sessionCtx.ap.beacon = NULL;
9502 }
9503 mutex_unlock(&pHddCtx->sap_lock);
9504 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009505
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 case WLAN_HDD_MONITOR:
9507 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009508
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 default:
9510 break;
9511 }
9512
9513 EXIT();
9514 return VOS_STATUS_SUCCESS;
9515}
9516
Kapil Gupta137ef892016-12-13 19:38:00 +05309517/**
9518 * wlan_hdd_restart_sap() - to restart SAP in driver internally
9519 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
9520 *
9521 * wlan_hdd_restart_sap first delete SAP and do cleanup.
9522 * After that WLANSAP_StartBss start re-start process of SAP.
9523 *
9524 * Return: None
9525 */
9526static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
9527{
9528 hdd_ap_ctx_t *pHddApCtx;
9529 hdd_hostapd_state_t *pHostapdState;
9530 VOS_STATUS vos_status;
9531 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
9532#ifdef CFG80211_DEL_STA_V2
9533 struct station_del_parameters delStaParams;
9534#endif
9535 tsap_Config_t *pConfig;
9536
9537 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
9538 pConfig = &pHddApCtx->sapConfig;
9539
9540 mutex_lock(&pHddCtx->sap_lock);
9541 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
9542#ifdef CFG80211_DEL_STA_V2
9543 delStaParams.mac = NULL;
9544 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
9545 delStaParams.reason_code = eCsrForcedDeauthSta;
9546 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
9547 &delStaParams);
9548#else
9549 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
9550 NULL);
9551#endif
9552 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
9553
9554 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
9555 vos_event_reset(&pHostapdState->vosEvent);
9556
9557 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9558 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
9559 10000);
9560 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9561 hddLog(LOGE, FL("SAP Stop Failed"));
9562 goto end;
9563 }
9564 }
9565 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
9566 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
9567 hddLog(LOG1, FL("SAP Stop Success"));
9568
9569 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
9570 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9571 goto end;
9572 }
9573
9574 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
9575 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
9576 hddLog(LOGE, FL("SAP Start Bss fail"));
9577 goto end;
9578 }
9579
9580 hddLog(LOG1, FL("Waiting for SAP to start"));
9581 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9582 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9583 hddLog(LOGE, FL("SAP Start failed"));
9584 goto end;
9585 }
9586 hddLog(LOG1, FL("SAP Start Success"));
9587 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
9588 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
9589 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309590 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
9591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
9592 vos_event_reset(&pHostapdState->vosEvent);
9593 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9594 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
9595 10000);
9596 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9597 hddLog(LOGE, FL("SAP Stop Failed"));
9598 goto end;
9599 }
9600 }
9601 }
Kapil Gupta137ef892016-12-13 19:38:00 +05309602 }
9603end:
9604 mutex_unlock(&pHddCtx->sap_lock);
9605 return;
9606}
9607
9608/**
9609 * __hdd_sap_restart_handle() - to handle restarting of SAP
9610 * @work: name of the work
9611 *
9612 * Purpose of this function is to trigger sap start. this function
9613 * will be called from workqueue.
9614 *
9615 * Return: void.
9616 */
9617static void __hdd_sap_restart_handle(struct work_struct *work)
9618{
9619 hdd_adapter_t *sap_adapter;
9620 hdd_context_t *hdd_ctx = container_of(work,
9621 hdd_context_t,
9622 sap_start_work);
9623 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
9624 vos_ssr_unprotect(__func__);
9625 return;
9626 }
9627 sap_adapter = hdd_get_adapter(hdd_ctx,
9628 WLAN_HDD_SOFTAP);
9629 if (sap_adapter == NULL) {
9630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9631 FL("sap_adapter is NULL"));
9632 vos_ssr_unprotect(__func__);
9633 return;
9634 }
9635
9636 if (hdd_ctx->is_ch_avoid_in_progress) {
9637 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
9638 wlan_hdd_restart_sap(sap_adapter);
9639 hdd_change_ch_avoidance_status(hdd_ctx, false);
9640 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +05309641 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
9642 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +05309643}
9644
9645/**
9646 * hdd_sap_restart_handle() - to handle restarting of SAP
9647 * @work: name of the work
9648 *
9649 * Purpose of this function is to trigger sap start. this function
9650 * will be called from workqueue.
9651 *
9652 * Return: void.
9653 */
9654static void hdd_sap_restart_handle(struct work_struct *work)
9655{
9656 vos_ssr_protect(__func__);
9657 __hdd_sap_restart_handle(work);
9658 vos_ssr_unprotect(__func__);
9659}
9660
9661
Abhishek Singh78c691f2017-11-30 13:48:44 +05309662/**
9663 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
9664 * @work: name of the work
9665 *
9666 * Purpose of this function is to force SCC using ECSA. This function
9667 * will be called from workqueue.
9668 *
9669 * Return: void.
9670 */
9671static void
9672__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
9673{
9674 hdd_adapter_t *sap_adapter;
9675 hdd_station_ctx_t *sta_ctx;
9676 hdd_adapter_t *sta_adapter;
9677 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
9678 hdd_context_t,
9679 ecsa_chan_change_work);
9680
9681 if (wlan_hdd_validate_context(hdd_ctx))
9682 return;
9683
9684 sap_adapter = hdd_get_adapter(hdd_ctx,
9685 WLAN_HDD_SOFTAP);
9686 if (!sap_adapter) {
9687 hddLog(LOGE, FL("sap_adapter is NULL"));
9688 return;
9689 }
9690
9691 sta_adapter = hdd_get_adapter(hdd_ctx,
9692 WLAN_HDD_INFRA_STATION);
9693 if (!sta_adapter) {
9694 hddLog(LOGE, FL("sta_adapter is NULL"));
9695 return;
9696 }
9697 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
9698
9699 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
9700 hddLog(LOGE, FL("sta not in connected state %d"),
9701 sta_ctx->conn_info.connState);
9702 return;
9703 }
9704
9705 hddLog(LOGE, FL("Switch SAP to SCC channel %d"),
9706 sta_ctx->conn_info.operationChannel);
9707 wlansap_set_channel_change((WLAN_HDD_GET_CTX(sap_adapter))->pvosContext,
9708 sta_ctx->conn_info.operationChannel, true);
9709}
9710
9711/**
9712 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
9713 * @work: name of the work
9714 *
9715 * Purpose of this function is to force SCC using ECSA. This function
9716 * will be called from workqueue.
9717 *
9718 * Return: void.
9719 */
9720static void
9721hdd_force_scc_with_ecsa_handle(struct work_struct *work)
9722{
9723 vos_ssr_protect(__func__);
9724 __hdd_force_scc_with_ecsa_handle(work);
9725 vos_ssr_unprotect(__func__);
9726}
9727
Jeff Johnson295189b2012-06-20 16:38:30 -07009728VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9729{
9730 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9731 VOS_STATUS status;
9732 hdd_adapter_t *pAdapter;
9733
9734 ENTER();
9735
9736 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9737
9738 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9739 {
9740 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009741
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309742 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009743
9744 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9745 pAdapterNode = pNext;
9746 }
9747
9748 EXIT();
9749
9750 return VOS_STATUS_SUCCESS;
9751}
9752
Rajeev Kumarf999e582014-01-09 17:33:29 -08009753
9754#ifdef FEATURE_WLAN_BATCH_SCAN
9755/**---------------------------------------------------------------------------
9756
9757 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9758 structures
9759
9760 \param - pAdapter Pointer to HDD adapter
9761
9762 \return - None
9763
9764 --------------------------------------------------------------------------*/
9765void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9766{
9767 tHddBatchScanRsp *pNode;
9768 tHddBatchScanRsp *pPrev;
9769
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309770 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009771 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309772 hddLog(VOS_TRACE_LEVEL_ERROR,
9773 "%s: Adapter context is Null", __func__);
9774 return;
9775 }
9776
9777 pNode = pAdapter->pBatchScanRsp;
9778 while (pNode)
9779 {
9780 pPrev = pNode;
9781 pNode = pNode->pNext;
9782 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009783 }
9784
9785 pAdapter->pBatchScanRsp = NULL;
9786 pAdapter->numScanList = 0;
9787 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9788 pAdapter->prev_batch_id = 0;
9789
9790 return;
9791}
9792#endif
9793
9794
Jeff Johnson295189b2012-06-20 16:38:30 -07009795VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9796{
9797 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9798 VOS_STATUS status;
9799 hdd_adapter_t *pAdapter;
9800
9801 ENTER();
9802
9803 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9804
9805 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9806 {
9807 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309810
9811 if (pHddCtx->cfg_ini->sap_internal_restart &&
9812 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
9813 hddLog(LOG1, FL("driver supports sap restart"));
9814 vos_flush_work(&pHddCtx->sap_start_work);
9815 hdd_sap_indicate_disconnect_for_sta(pAdapter);
9816 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309817 hdd_softap_deinit_tx_rx(pAdapter, true);
9818 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309819 } else {
9820 netif_carrier_off(pAdapter->dev);
9821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009823 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9824
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309826
Katya Nigam1fd24402015-02-16 14:52:19 +05309827 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9828 hdd_ibss_deinit_tx_rx(pAdapter);
9829
Nirav Shah7e3c8132015-06-22 23:51:42 +05309830 status = hdd_sta_id_hash_detach(pAdapter);
9831 if (status != VOS_STATUS_SUCCESS)
9832 hddLog(VOS_TRACE_LEVEL_ERROR,
9833 FL("sta id hash detach failed for session id %d"),
9834 pAdapter->sessionId);
9835
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309836 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9837
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309838 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9839 {
9840 hdd_wmm_adapter_close( pAdapter );
9841 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009843
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309844 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9845 {
9846 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9847 }
9848
Rajeev Kumarf999e582014-01-09 17:33:29 -08009849#ifdef FEATURE_WLAN_BATCH_SCAN
9850 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9851 {
9852 hdd_deinit_batch_scan(pAdapter);
9853 }
9854#endif
9855
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309856#ifdef FEATURE_WLAN_TDLS
9857 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309858 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309859 mutex_unlock(&pHddCtx->tdls_lock);
9860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9862 pAdapterNode = pNext;
9863 }
9864
9865 EXIT();
9866
9867 return VOS_STATUS_SUCCESS;
9868}
9869
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309870/**
Abhishek Singh5a597e62016-12-05 15:16:30 +05309871 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
9872 * @wiphy: wiphy
9873 * @channel: channel of the BSS to find
9874 * @bssid: bssid of the BSS to find
9875 * @ssid: ssid of the BSS to find
9876 * @ssid_len: ssid len of of the BSS to find
9877 *
9878 * The API is a wrapper to get bss from kernel matching the chan,
9879 * bssid and ssid
9880 *
9881 * Return: Void
9882 */
9883#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
9884 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
9885
9886struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
9887 struct ieee80211_channel *channel,
9888 const u8 *bssid,
9889 const u8 *ssid, size_t ssid_len)
9890{
9891 return cfg80211_get_bss(wiphy, channel, bssid,
9892 ssid, ssid_len,
9893 WLAN_CAPABILITY_ESS,
9894 WLAN_CAPABILITY_ESS);
9895}
9896#else
9897struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
9898 struct ieee80211_channel *channel,
9899 const u8 *bssid,
9900 const u8 *ssid, size_t ssid_len)
9901{
9902 return cfg80211_get_bss(wiphy, channel, bssid,
9903 ssid, ssid_len,
9904 IEEE80211_BSS_TYPE_ESS,
9905 IEEE80211_PRIVACY_ANY);
9906}
9907#endif
9908
9909/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309910 * hdd_connect_result() - API to send connection status to supplicant
9911 * @dev: network device
9912 * @bssid: bssid to which we want to associate
9913 * @roam_info: information about connected bss
9914 * @req_ie: Request Information Element
9915 * @req_ie_len: len of the req IE
9916 * @resp_ie: Response IE
9917 * @resp_ie_len: len of ht response IE
9918 * @status: status
9919 * @gfp: Kernel Flag
9920 *
9921 * The API is a wrapper to send connection status to supplicant
9922 *
9923 * Return: Void
9924 */
9925#if defined CFG80211_CONNECT_BSS
9926void hdd_connect_result(struct net_device *dev,
9927 const u8 *bssid,
9928 tCsrRoamInfo *roam_info,
9929 const u8 *req_ie,
9930 size_t req_ie_len,
9931 const u8 *resp_ie,
9932 size_t resp_ie_len,
9933 u16 status,
9934 gfp_t gfp)
9935{
9936 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
9937 struct cfg80211_bss *bss = NULL;
9938
9939 if (WLAN_STATUS_SUCCESS == status) {
9940 struct ieee80211_channel *chan;
9941 int freq;
9942 int chan_no = roam_info->pBssDesc->channelId;;
9943
9944 if (chan_no <= 14)
9945 freq = ieee80211_channel_to_frequency(chan_no,
9946 IEEE80211_BAND_2GHZ);
9947 else
9948 freq = ieee80211_channel_to_frequency(chan_no,
9949 IEEE80211_BAND_5GHZ);
9950
9951 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +05309952 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
9953 chan, bssid,
9954 roam_info->u.pConnectedProfile->SSID.ssId,
9955 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309956 }
9957
9958 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
9959 resp_ie, resp_ie_len, status, gfp);
9960}
9961#else
9962void hdd_connect_result(struct net_device *dev,
9963 const u8 *bssid,
9964 tCsrRoamInfo *roam_info,
9965 const u8 *req_ie,
9966 size_t req_ie_len,
9967 const u8 * resp_ie,
9968 size_t resp_ie_len,
9969 u16 status,
9970 gfp_t gfp)
9971{
9972 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
9973 resp_ie, resp_ie_len, status, gfp);
9974}
9975#endif
9976
Jeff Johnson295189b2012-06-20 16:38:30 -07009977VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9978{
9979 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9980 VOS_STATUS status;
9981 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309982 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009983
9984 ENTER();
9985
9986 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9987
9988 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9989 {
9990 pAdapter = pAdapterNode->pAdapter;
9991
Kumar Anand82c009f2014-05-29 00:29:42 -07009992 hdd_wmm_init( pAdapter );
9993
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 switch(pAdapter->device_mode)
9995 {
9996 case WLAN_HDD_INFRA_STATION:
9997 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009998 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309999
10000 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
10001
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 hdd_init_station_mode(pAdapter);
10003 /* Open the gates for HDD to receive Wext commands */
10004 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010005 pHddCtx->scan_info.mScanPending = FALSE;
10006 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007
10008 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053010009 if (!pHddCtx->isLogpInProgress)
10010 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010011
10012 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010013 if (eConnectionState_Associated == connState ||
10014 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 {
10016 union iwreq_data wrqu;
10017 memset(&wrqu, '\0', sizeof(wrqu));
10018 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10019 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10020 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010021 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010022
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053010024 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053010025 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070010026 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010027 else if (eConnectionState_Connecting == connState)
10028 {
10029 /*
10030 * Indicate connect failure to supplicant if we were in the
10031 * process of connecting
10032 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010033 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010034 NULL, 0, NULL, 0,
10035 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
10036 GFP_KERNEL);
10037 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 break;
10039
10040 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010041 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010042 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010043 status = hdd_sta_id_hash_attach(pAdapter);
10044 if (VOS_STATUS_SUCCESS != status)
10045 {
10046 hddLog(VOS_TRACE_LEVEL_FATAL,
10047 FL("failed to attach hash for"));
10048 }
10049 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 break;
10051
10052 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070010053 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070010055 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 break;
10057
10058 case WLAN_HDD_MONITOR:
10059 /* monitor interface start */
10060 break;
10061 default:
10062 break;
10063 }
10064
10065 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10066 pAdapterNode = pNext;
10067 }
10068
10069 EXIT();
10070
10071 return VOS_STATUS_SUCCESS;
10072}
10073
10074VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
10075{
10076 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10077 hdd_adapter_t *pAdapter;
10078 VOS_STATUS status;
10079 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010080 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010081
10082 ENTER();
10083
10084 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10085
10086 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10087 {
10088 pAdapter = pAdapterNode->pAdapter;
10089
10090 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10091 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10092 {
10093 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10094 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10095
Abhishek Singhf4669da2014-05-26 15:07:49 +053010096 hddLog(VOS_TRACE_LEVEL_INFO,
10097 "%s: Set HDD connState to eConnectionState_NotConnected",
10098 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053010099 spin_lock_bh(&pAdapter->lock_for_active_session);
10100 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10101 {
10102 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053010105 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 init_completion(&pAdapter->disconnect_comp_var);
10107 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
10108 eCSR_DISCONNECT_REASON_UNSPECIFIED);
10109
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010110 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 &pAdapter->disconnect_comp_var,
10112 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010113 if (0 >= ret)
10114 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
10115 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070010116
10117 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
10118 pHddCtx->isAmpAllowed = VOS_FALSE;
10119 sme_RoamConnect(pHddCtx->hHal,
10120 pAdapter->sessionId, &(pWextState->roamProfile),
10121 &roamId);
10122 }
10123
10124 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10125 pAdapterNode = pNext;
10126 }
10127
10128 EXIT();
10129
10130 return VOS_STATUS_SUCCESS;
10131}
10132
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010133void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
10134{
10135 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10136 VOS_STATUS status;
10137 hdd_adapter_t *pAdapter;
10138 hdd_station_ctx_t *pHddStaCtx;
10139 hdd_ap_ctx_t *pHddApCtx;
10140 hdd_hostapd_state_t * pHostapdState;
10141 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
10142 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
10143 const char *p2pMode = "DEV";
10144 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010145
10146 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10147 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10148 {
10149 pAdapter = pAdapterNode->pAdapter;
10150 switch (pAdapter->device_mode) {
10151 case WLAN_HDD_INFRA_STATION:
10152 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10153 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
10154 staChannel = pHddStaCtx->conn_info.operationChannel;
10155 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
10156 }
10157 break;
10158 case WLAN_HDD_P2P_CLIENT:
10159 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10160 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
10161 p2pChannel = pHddStaCtx->conn_info.operationChannel;
10162 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
10163 p2pMode = "CLI";
10164 }
10165 break;
10166 case WLAN_HDD_P2P_GO:
10167 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10168 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10169 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
10170 p2pChannel = pHddApCtx->operatingChannel;
10171 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
10172 }
10173 p2pMode = "GO";
10174 break;
10175 case WLAN_HDD_SOFTAP:
10176 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10177 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10178 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
10179 apChannel = pHddApCtx->operatingChannel;
10180 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
10181 }
10182 break;
10183 default:
10184 break;
10185 }
10186 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10187 pAdapterNode = pNext;
10188 }
10189 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
10190 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
10191 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053010192 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
10193 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010194 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053010195 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010196 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
10197 }
10198 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053010199 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010200 apChannel, MAC_ADDR_ARRAY(apBssid));
10201 }
10202
10203 if (p2pChannel > 0 && apChannel > 0) {
10204 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
10205 }
10206}
10207
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010208bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010209{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010210 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070010211}
10212
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010213/* Once SSR is disabled then it cannot be set. */
10214void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070010215{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010216 if (HDD_SSR_DISABLED == isSsrRequired)
10217 return;
10218
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 isSsrRequired = value;
10220}
10221
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053010222void hdd_set_pre_close( hdd_context_t *pHddCtx)
10223{
10224 sme_PreClose(pHddCtx->hHal);
10225}
10226
Jeff Johnson295189b2012-06-20 16:38:30 -070010227VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
10228 hdd_adapter_list_node_t** ppAdapterNode)
10229{
10230 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010231 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010232 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
10233 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010234 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 return status;
10236}
10237
10238VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
10239 hdd_adapter_list_node_t* pAdapterNode,
10240 hdd_adapter_list_node_t** pNextAdapterNode)
10241{
10242 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010243 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
10245 (hdd_list_node_t*) pAdapterNode,
10246 (hdd_list_node_t**)pNextAdapterNode );
10247
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010248 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 return status;
10250}
10251
10252VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
10253 hdd_adapter_list_node_t* pAdapterNode)
10254{
10255 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010256 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010257 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
10258 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010259 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 return status;
10261}
10262
10263VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
10264 hdd_adapter_list_node_t** ppAdapterNode)
10265{
10266 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010267 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
10269 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010270 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 return status;
10272}
10273
10274VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
10275 hdd_adapter_list_node_t* pAdapterNode)
10276{
10277 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010278 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
10280 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010281 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 return status;
10283}
10284
10285VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
10286 hdd_adapter_list_node_t* pAdapterNode)
10287{
10288 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010289 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
10291 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010292 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 return status;
10294}
10295
10296hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
10297 tSirMacAddr macAddr )
10298{
10299 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10300 hdd_adapter_t *pAdapter;
10301 VOS_STATUS status;
10302
10303 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10304
10305 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10306 {
10307 pAdapter = pAdapterNode->pAdapter;
10308
10309 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
10310 macAddr, sizeof(tSirMacAddr) ) )
10311 {
10312 return pAdapter;
10313 }
10314 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10315 pAdapterNode = pNext;
10316 }
10317
10318 return NULL;
10319
10320}
10321
10322hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
10323{
10324 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10325 hdd_adapter_t *pAdapter;
10326 VOS_STATUS status;
10327
10328 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10329
10330 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10331 {
10332 pAdapter = pAdapterNode->pAdapter;
10333
10334 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
10335 IFNAMSIZ ) )
10336 {
10337 return pAdapter;
10338 }
10339 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10340 pAdapterNode = pNext;
10341 }
10342
10343 return NULL;
10344
10345}
10346
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053010347hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
10348 tANI_U32 sme_session_id )
10349{
10350 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10351 hdd_adapter_t *pAdapter;
10352 VOS_STATUS vos_status;
10353
10354
10355 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
10356
10357 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
10358 {
10359 pAdapter = pAdapterNode->pAdapter;
10360
10361 if (pAdapter->sessionId == sme_session_id)
10362 return pAdapter;
10363
10364 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
10365 pAdapterNode = pNext;
10366 }
10367
10368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10369 "%s: sme_session_id %d does not exist with host",
10370 __func__, sme_session_id);
10371
10372 return NULL;
10373}
10374
Jeff Johnson295189b2012-06-20 16:38:30 -070010375hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
10376{
10377 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10378 hdd_adapter_t *pAdapter;
10379 VOS_STATUS status;
10380
10381 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10382
10383 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10384 {
10385 pAdapter = pAdapterNode->pAdapter;
10386
10387 if( pAdapter && (mode == pAdapter->device_mode) )
10388 {
10389 return pAdapter;
10390 }
10391 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10392 pAdapterNode = pNext;
10393 }
10394
10395 return NULL;
10396
10397}
10398
10399//Remove this function later
10400hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
10401{
10402 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10403 hdd_adapter_t *pAdapter;
10404 VOS_STATUS status;
10405
10406 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10407
10408 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10409 {
10410 pAdapter = pAdapterNode->pAdapter;
10411
10412 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
10413 {
10414 return pAdapter;
10415 }
10416
10417 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10418 pAdapterNode = pNext;
10419 }
10420
10421 return NULL;
10422
10423}
10424
Jeff Johnson295189b2012-06-20 16:38:30 -070010425/**---------------------------------------------------------------------------
10426
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053010427 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070010428
10429 This API returns the operating channel of the requested device mode
10430
10431 \param - pHddCtx - Pointer to the HDD context.
10432 - mode - Device mode for which operating channel is required
10433 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
10434 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
10435 \return - channel number. "0" id the requested device is not found OR it is not connected.
10436 --------------------------------------------------------------------------*/
10437v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
10438{
10439 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10440 VOS_STATUS status;
10441 hdd_adapter_t *pAdapter;
10442 v_U8_t operatingChannel = 0;
10443
10444 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10445
10446 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10447 {
10448 pAdapter = pAdapterNode->pAdapter;
10449
10450 if( mode == pAdapter->device_mode )
10451 {
10452 switch(pAdapter->device_mode)
10453 {
10454 case WLAN_HDD_INFRA_STATION:
10455 case WLAN_HDD_P2P_CLIENT:
10456 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
10457 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
10458 break;
10459 case WLAN_HDD_SOFTAP:
10460 case WLAN_HDD_P2P_GO:
10461 /*softap connection info */
10462 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10463 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
10464 break;
10465 default:
10466 break;
10467 }
10468
10469 break; //Found the device of interest. break the loop
10470 }
10471
10472 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10473 pAdapterNode = pNext;
10474 }
10475 return operatingChannel;
10476}
10477
10478#ifdef WLAN_FEATURE_PACKET_FILTERING
10479/**---------------------------------------------------------------------------
10480
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010481 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070010482
10483 This used to set the multicast address list.
10484
10485 \param - dev - Pointer to the WLAN device.
10486 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010487 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070010488
10489 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010490static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070010491{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010492 hdd_adapter_t *pAdapter;
10493 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010495 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010498 ENTER();
10499
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010500 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010501 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 {
10503 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010504 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010505 return;
10506 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010507 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10508 ret = wlan_hdd_validate_context(pHddCtx);
10509 if (0 != ret)
10510 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010511 return;
10512 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 if (dev->flags & IFF_ALLMULTI)
10514 {
10515 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010516 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010517 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010519 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 {
10521 mc_count = netdev_mc_count(dev);
10522 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010523 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
10525 {
10526 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010527 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010528 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 return;
10530 }
10531
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010532 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070010533
10534 netdev_for_each_mc_addr(ha, dev) {
10535 if (i == mc_count)
10536 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010537 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
10538 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080010539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010540 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010541 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 i++;
10543 }
10544 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010545
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053010546 if (pHddCtx->hdd_wlan_suspended)
10547 {
10548 /*
10549 * Configure the Mcast address list to FW
10550 * If wlan is already in suspend mode
10551 */
10552 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
10553 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010554 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 return;
10556}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010557
10558static void hdd_set_multicast_list(struct net_device *dev)
10559{
10560 vos_ssr_protect(__func__);
10561 __hdd_set_multicast_list(dev);
10562 vos_ssr_unprotect(__func__);
10563}
Jeff Johnson295189b2012-06-20 16:38:30 -070010564#endif
10565
10566/**---------------------------------------------------------------------------
10567
10568 \brief hdd_select_queue() -
10569
10570 This function is registered with the Linux OS for network
10571 core to decide which queue to use first.
10572
10573 \param - dev - Pointer to the WLAN device.
10574 - skb - Pointer to OS packet (sk_buff).
10575 \return - ac, Queue Index/access category corresponding to UP in IP header
10576
10577 --------------------------------------------------------------------------*/
10578v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053010579 struct sk_buff *skb
10580#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
10581 , void *accel_priv
10582#endif
10583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
10584 , select_queue_fallback_t fallback
10585#endif
10586)
Jeff Johnson295189b2012-06-20 16:38:30 -070010587{
10588 return hdd_wmm_select_queue(dev, skb);
10589}
10590
10591
10592/**---------------------------------------------------------------------------
10593
10594 \brief hdd_wlan_initial_scan() -
10595
10596 This function triggers the initial scan
10597
10598 \param - pAdapter - Pointer to the HDD adapter.
10599
10600 --------------------------------------------------------------------------*/
10601void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
10602{
10603 tCsrScanRequest scanReq;
10604 tCsrChannelInfo channelInfo;
10605 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070010606 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10608
10609 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
10610 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
10611 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
10612
10613 if(sme_Is11dSupported(pHddCtx->hHal))
10614 {
10615 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
10616 if ( HAL_STATUS_SUCCESS( halStatus ) )
10617 {
10618 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
10619 if( !scanReq.ChannelInfo.ChannelList )
10620 {
10621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
10622 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010623 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 return;
10625 }
10626 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
10627 channelInfo.numOfChannels);
10628 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
10629 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010630 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 }
10632
10633 scanReq.scanType = eSIR_PASSIVE_SCAN;
10634 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
10635 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10636 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10637 }
10638 else
10639 {
10640 scanReq.scanType = eSIR_ACTIVE_SCAN;
10641 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10642 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10643 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10644 }
10645
10646 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10647 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10648 {
10649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10650 __func__, halStatus );
10651 }
10652
10653 if(sme_Is11dSupported(pHddCtx->hHal))
10654 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10655}
10656
Jeff Johnson295189b2012-06-20 16:38:30 -070010657/**---------------------------------------------------------------------------
10658
10659 \brief hdd_full_power_callback() - HDD full power callback function
10660
10661 This is the function invoked by SME to inform the result of a full power
10662 request issued by HDD
10663
10664 \param - callbackcontext - Pointer to cookie
10665 \param - status - result of request
10666
10667 \return - None
10668
10669 --------------------------------------------------------------------------*/
10670static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10671{
Jeff Johnson72a40512013-12-19 10:14:15 -080010672 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010673
10674 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070010675 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010676
10677 if (NULL == callbackContext)
10678 {
10679 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070010680 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010681 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 return;
10683 }
10684
Jeff Johnson72a40512013-12-19 10:14:15 -080010685 /* there is a race condition that exists between this callback
10686 function and the caller since the caller could time out either
10687 before or while this code is executing. we use a spinlock to
10688 serialize these actions */
10689 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010690
10691 if (POWER_CONTEXT_MAGIC != pContext->magic)
10692 {
10693 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010694 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 hddLog(VOS_TRACE_LEVEL_WARN,
10696 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010697 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 return;
10699 }
10700
Jeff Johnson72a40512013-12-19 10:14:15 -080010701 /* context is valid so caller is still waiting */
10702
10703 /* paranoia: invalidate the magic */
10704 pContext->magic = 0;
10705
10706 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010708
10709 /* serialization is complete */
10710 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010711}
10712
Katya Nigamf0511f62015-05-05 16:40:57 +053010713void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10714{
10715 pMonCtx->typeSubtypeBitmap = 0;
10716 if( type%10 ) /* Management Packets */
10717 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10718 type/=10;
10719 if( type%10 ) /* Control Packets */
10720 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10721 type/=10;
10722 if( type%10 ) /* Data Packets */
10723 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10724}
10725
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010726VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10727 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010728{
10729 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010730 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010731
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010732 if (MON_MODE_START == pMonCtx->state)
10733 monMsg.type = WDA_MON_START_REQ;
10734 else if (MON_MODE_STOP == pMonCtx->state)
10735 monMsg.type = WDA_MON_STOP_REQ;
10736 else {
10737 hddLog(VOS_TRACE_LEVEL_ERROR,
10738 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010739 return VOS_STATUS_E_FAILURE;
10740 }
10741
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010742 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10743 if (pMonModeReq == NULL) {
10744 hddLog(VOS_TRACE_LEVEL_ERROR,
10745 FL("fail to allocate memory for monitor mode req"));
10746 return VOS_STATUS_E_FAILURE;
10747 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010748
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010749 pMonModeReq->magic = magic;
10750 pMonModeReq->cmpVar = cmpVar;
10751 pMonModeReq->data = pMonCtx;
10752 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010753
Katya Nigamf0511f62015-05-05 16:40:57 +053010754 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010755 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010756 monMsg.bodyval = 0;
10757
10758 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10759 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10760 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010761 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010762 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010763 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010764}
10765
Katya Nigame7b69a82015-04-28 15:24:06 +053010766void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10767{
10768 VOS_STATUS vosStatus;
10769 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010770 long ret;
10771 hdd_mon_ctx_t *pMonCtx = NULL;
10772 v_U32_t magic;
10773 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010774
Katya Nigame7b69a82015-04-28 15:24:06 +053010775 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10776 if(pAdapter == NULL || pVosContext == NULL)
10777 {
10778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10779 return ;
10780 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010781
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010782 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10783 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10784 pMonCtx->state = MON_MODE_STOP;
10785 magic = MON_MODE_MSG_MAGIC;
10786 init_completion(&cmpVar);
10787 if (VOS_STATUS_SUCCESS !=
10788 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10789 pMonCtx, hdd_monPostMsgCb)) {
10790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10791 FL("failed to post MON MODE REQ"));
10792 pMonCtx->state = MON_MODE_START;
10793 magic = 0;
10794 return;
10795 }
10796 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10797 magic = 0;
10798 if (ret <= 0 ) {
10799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10800 FL("timeout on monitor mode completion %ld"), ret);
10801 }
10802 }
10803
Katya Nigame7b69a82015-04-28 15:24:06 +053010804 hdd_UnregisterWext(pAdapter->dev);
10805
10806 vos_mon_stop( pVosContext );
10807
10808 vosStatus = vos_sched_close( pVosContext );
10809 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10810 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10811 "%s: Failed to close VOSS Scheduler",__func__);
10812 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10813 }
10814
10815 vosStatus = vos_nv_close();
10816 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10817 {
10818 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10819 "%s: Failed to close NV", __func__);
10820 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10821 }
10822
10823 vos_close(pVosContext);
10824
10825 #ifdef WLAN_KD_READY_NOTIFIER
10826 nl_srv_exit(pHddCtx->ptt_pid);
10827 #else
10828 nl_srv_exit();
10829 #endif
10830
Katya Nigame7b69a82015-04-28 15:24:06 +053010831 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010832}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010833/**
10834 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10835 * @ wiphy: the wiphy to validate against
10836 *
10837 * Return: void
10838 */
10839void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10840{
10841 int i =0;
10842 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10843 {
10844 if (NULL != wiphy->bands[i] &&
10845 (NULL != wiphy->bands[i]->channels))
10846 {
10847 vos_mem_free(wiphy->bands[i]->channels);
10848 wiphy->bands[i]->channels = NULL;
10849 }
10850 }
10851}
Jeff Johnson295189b2012-06-20 16:38:30 -070010852/**---------------------------------------------------------------------------
10853
10854 \brief hdd_wlan_exit() - HDD WLAN exit function
10855
10856 This is the driver exit point (invoked during rmmod)
10857
10858 \param - pHddCtx - Pointer to the HDD Context
10859
10860 \return - None
10861
10862 --------------------------------------------------------------------------*/
10863void hdd_wlan_exit(hdd_context_t *pHddCtx)
10864{
10865 eHalStatus halStatus;
10866 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10867 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010868 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010869 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010870 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010872 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010873
10874 ENTER();
10875
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010876
Katya Nigame7b69a82015-04-28 15:24:06 +053010877 if (VOS_MONITOR_MODE == hdd_get_conparam())
10878 {
10879 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10880 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010881 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010882 }
10883 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010884 {
10885 // Unloading, restart logic is no more required.
10886 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010887
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010888#ifdef FEATURE_WLAN_TDLS
10889 /* At the time of driver unloading; if tdls connection is present;
10890 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10891 * wlan_hdd_tdls_find_peer always checks for valid context;
10892 * as load/unload in progress there can be a race condition.
10893 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10894 * when tdls state is enabled.
10895 * As soon as driver set load/unload flag; tdls flag also needs
10896 * to be disabled so that hdd_rx_packet_cbk won't call
10897 * wlan_hdd_tdls_find_peer.
10898 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010899 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10900 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010901#endif
10902
c_hpothu5ab05e92014-06-13 17:34:05 +053010903 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10904 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010906 pAdapter = pAdapterNode->pAdapter;
10907 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010909 /* Disable TX on the interface, after this hard_start_xmit() will
10910 * not be called on that interface
10911 */
10912 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10913 netif_tx_disable(pAdapter->dev);
10914
10915 /* Mark the interface status as "down" for outside world */
10916 netif_carrier_off(pAdapter->dev);
10917
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010918 /* DeInit the adapter. This ensures that all data packets
10919 * are freed.
10920 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010921#ifdef FEATURE_WLAN_TDLS
10922 mutex_lock(&pHddCtx->tdls_lock);
10923#endif
c_hpothu002231a2015-02-05 14:58:51 +053010924 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010925#ifdef FEATURE_WLAN_TDLS
10926 mutex_unlock(&pHddCtx->tdls_lock);
10927#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010928 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10929
10930 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010931
c_hpothu5ab05e92014-06-13 17:34:05 +053010932 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10933 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10934 {
10935 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10936 hdd_UnregisterWext(pAdapter->dev);
10937 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010938
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010940 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10941 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010942 }
mukul sharmabab477d2015-06-11 17:14:55 +053010943
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010944 // Cancel any outstanding scan requests. We are about to close all
10945 // of our adapters, but an adapter structure is what SME passes back
10946 // to our callback function. Hence if there are any outstanding scan
10947 // requests then there is a race condition between when the adapter
10948 // is closed and when the callback is invoked.We try to resolve that
10949 // race condition here by canceling any outstanding scans before we
10950 // close the adapters.
10951 // Note that the scans may be cancelled in an asynchronous manner,
10952 // so ideally there needs to be some kind of synchronization. Rather
10953 // than introduce a new synchronization here, we will utilize the
10954 // fact that we are about to Request Full Power, and since that is
10955 // synchronized, the expectation is that by the time Request Full
10956 // Power has completed all scans will be cancelled.
10957 if (pHddCtx->scan_info.mScanPending)
10958 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010959 if(NULL != pAdapter)
10960 {
10961 hddLog(VOS_TRACE_LEVEL_INFO,
10962 FL("abort scan mode: %d sessionId: %d"),
10963 pAdapter->device_mode,
10964 pAdapter->sessionId);
10965 }
10966 hdd_abort_mac_scan(pHddCtx,
10967 pHddCtx->scan_info.sessionId,
10968 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010969 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010971 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010972 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010973 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010974 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10975 {
10976 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10978 "%s: in middle of FTM START", __func__);
10979 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10980 msecs_to_jiffies(20000));
10981 if(!lrc)
10982 {
10983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10984 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10985 }
10986 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010987 wlan_hdd_ftm_close(pHddCtx);
10988 goto free_hdd_ctx;
10989 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010990
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 /* DeRegister with platform driver as client for Suspend/Resume */
10992 vosStatus = hddDeregisterPmOps(pHddCtx);
10993 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10994 {
10995 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10996 VOS_ASSERT(0);
10997 }
10998
10999 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
11000 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
11001 {
11002 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
11003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011004
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011005 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053011006 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
11007 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011008 {
11009 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
11010 }
11011
11012 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053011013 if ((pHddCtx->cfg_ini->dynSplitscan) &&
11014 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
11015 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011016 {
11017 hddLog(VOS_TRACE_LEVEL_ERROR,
11018 "%s: Cannot deallocate Traffic monitor timer", __func__);
11019 }
11020
Bhargav Shahd0715912015-10-01 18:17:37 +053011021 if (VOS_TIMER_STATE_RUNNING ==
11022 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11023 vos_timer_stop(&pHddCtx->delack_timer);
11024 }
11025
11026 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
11027 &pHddCtx->delack_timer))) {
11028 hddLog(VOS_TRACE_LEVEL_ERROR,
11029 "%s: Cannot deallocate Bus bandwidth timer", __func__);
11030 }
11031
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053011032 if (VOS_TIMER_STATE_RUNNING ==
11033 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
11034 vos_timer_stop(&pHddCtx->tdls_source_timer);
11035 }
11036
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053011037 vos_set_snoc_high_freq_voting(false);
11038
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053011039 vos_timer_destroy(&pHddCtx->tdls_source_timer);
11040
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 //Disable IMPS/BMPS as we do not want the device to enter any power
11042 //save mode during shutdown
11043 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
11044 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
11045 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
11046
11047 //Ensure that device is in full power as we will touch H/W during vos_Stop
11048 init_completion(&powerContext.completion);
11049 powerContext.magic = POWER_CONTEXT_MAGIC;
11050
11051 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
11052 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
11053
11054 if (eHAL_STATUS_SUCCESS != halStatus)
11055 {
11056 if (eHAL_STATUS_PMC_PENDING == halStatus)
11057 {
11058 /* request was sent -- wait for the response */
11059 lrc = wait_for_completion_interruptible_timeout(
11060 &powerContext.completion,
11061 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 if (lrc <= 0)
11063 {
11064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011065 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 }
11067 }
11068 else
11069 {
11070 hddLog(VOS_TRACE_LEVEL_ERROR,
11071 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011072 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 /* continue -- need to clean up as much as possible */
11074 }
11075 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053011076 if ((eHAL_STATUS_SUCCESS == halStatus) ||
11077 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
11078 {
11079 /* This will issue a dump command which will clean up
11080 BTQM queues and unblock MC thread */
11081 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
11082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011083
Jeff Johnson72a40512013-12-19 10:14:15 -080011084 /* either we never sent a request, we sent a request and received a
11085 response or we sent a request and timed out. if we never sent a
11086 request or if we sent a request and got a response, we want to
11087 clear the magic out of paranoia. if we timed out there is a
11088 race condition such that the callback function could be
11089 executing at the same time we are. of primary concern is if the
11090 callback function had already verified the "magic" but had not
11091 yet set the completion variable when a timeout occurred. we
11092 serialize these activities by invalidating the magic while
11093 holding a shared spinlock which will cause us to block if the
11094 callback is currently executing */
11095 spin_lock(&hdd_context_lock);
11096 powerContext.magic = 0;
11097 spin_unlock(&hdd_context_lock);
11098
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053011099 /* If Device is shutdown, no point for SME to wait for responses
11100 from device. Pre Close SME */
11101 if(wcnss_device_is_shutdown())
11102 {
11103 sme_PreClose(pHddCtx->hHal);
11104 }
Yue Ma0d4891e2013-08-06 17:01:45 -070011105 hdd_debugfs_exit(pHddCtx);
11106
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011107#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053011108 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011109 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
11110#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053011111 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011112 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
11113
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 // Unregister the Net Device Notifier
11115 unregister_netdevice_notifier(&hdd_netdev_notifier);
11116
Jeff Johnson295189b2012-06-20 16:38:30 -070011117 hdd_stop_all_adapters( pHddCtx );
11118
Jeff Johnson295189b2012-06-20 16:38:30 -070011119#ifdef WLAN_BTAMP_FEATURE
11120 vosStatus = WLANBAP_Stop(pVosContext);
11121 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11122 {
11123 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11124 "%s: Failed to stop BAP",__func__);
11125 }
11126#endif //WLAN_BTAMP_FEATURE
11127
11128 //Stop all the modules
11129 vosStatus = vos_stop( pVosContext );
11130 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11131 {
11132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11133 "%s: Failed to stop VOSS",__func__);
11134 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011135 if (isSsrPanicOnFailure())
11136 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 }
11138
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011141
11142 //Close the scheduler before calling vos_close to make sure no thread is
11143 // scheduled after the each module close is called i.e after all the data
11144 // structures are freed.
11145 vosStatus = vos_sched_close( pVosContext );
11146 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
11147 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11148 "%s: Failed to close VOSS Scheduler",__func__);
11149 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11150 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011151#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
11152 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011153 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070011154#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080011155 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011156 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011157
Mihir Shete7a24b5f2013-12-21 12:18:31 +053011158#ifdef CONFIG_ENABLE_LINUX_REG
11159 vosStatus = vos_nv_close();
11160 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11161 {
11162 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11163 "%s: Failed to close NV", __func__);
11164 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11165 }
11166#endif
11167
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 //Close VOSS
11169 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
11170 vos_close(pVosContext);
11171
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 //Close Watchdog
11173 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11174 vos_watchdog_close(pVosContext);
11175
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053011176 //Clean up HDD Nlink Service
11177 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053011178
Manjeet Singh47ee8472016-04-11 11:57:18 +053011179 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053011180 wlan_free_fwr_mem_dump_buffer();
11181 memdump_deinit();
11182
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053011183#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011184 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053011185 {
11186 wlan_logging_sock_deactivate_svc();
11187 }
11188#endif
11189
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053011190#ifdef WLAN_KD_READY_NOTIFIER
11191 nl_srv_exit(pHddCtx->ptt_pid);
11192#else
11193 nl_srv_exit();
11194#endif /* WLAN_KD_READY_NOTIFIER */
11195
Abhishek Singh00b71972016-01-07 10:51:04 +053011196#ifdef WLAN_FEATURE_RMC
11197 hdd_close_cesium_nl_sock();
11198#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053011199
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 hdd_close_all_adapters( pHddCtx );
11201
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011202 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053011203 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053011204 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011205
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053011206free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 /* free the power on lock from platform driver */
11208 if (free_riva_power_on_lock("wlan"))
11209 {
11210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
11211 __func__);
11212 }
11213
c_hpothu78c7b602014-05-17 17:35:49 +053011214 //Free up dynamically allocated members inside HDD Adapter
11215 if (pHddCtx->cfg_ini)
11216 {
11217 kfree(pHddCtx->cfg_ini);
11218 pHddCtx->cfg_ini= NULL;
11219 }
11220
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053011221 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070011222 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053011223 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
11224 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070011225 {
11226 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053011227 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070011228 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 if (hdd_is_ssr_required())
11231 {
11232 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070011233 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 msleep(5000);
11235 }
11236 hdd_set_ssr_required (VOS_FALSE);
11237}
11238
11239
11240/**---------------------------------------------------------------------------
11241
11242 \brief hdd_update_config_from_nv() - Function to update the contents of
11243 the running configuration with parameters taken from NV storage
11244
11245 \param - pHddCtx - Pointer to the HDD global context
11246
11247 \return - VOS_STATUS_SUCCESS if successful
11248
11249 --------------------------------------------------------------------------*/
11250static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
11251{
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 v_BOOL_t itemIsValid = VOS_FALSE;
11253 VOS_STATUS status;
11254 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
11255 v_U8_t macLoop;
11256
11257 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
11258 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
11259 if(status != VOS_STATUS_SUCCESS)
11260 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011261 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 return VOS_STATUS_E_FAILURE;
11263 }
11264
11265 if (itemIsValid == VOS_TRUE)
11266 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011267 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
11269 VOS_MAX_CONCURRENCY_PERSONA);
11270 if(status != VOS_STATUS_SUCCESS)
11271 {
11272 /* Get MAC from NV fail, not update CFG info
11273 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080011274 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 return VOS_STATUS_E_FAILURE;
11276 }
11277
11278 /* If first MAC is not valid, treat all others are not valid
11279 * Then all MACs will be got from ini file */
11280 if(vos_is_macaddr_zero(&macFromNV[0]))
11281 {
11282 /* MAC address in NV file is not configured yet */
11283 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
11284 return VOS_STATUS_E_INVAL;
11285 }
11286
11287 /* Get MAC address from NV, update CFG info */
11288 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
11289 {
11290 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
11291 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011292 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 /* This MAC is not valid, skip it
11294 * This MAC will be got from ini file */
11295 }
11296 else
11297 {
11298 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
11299 (v_U8_t *)&macFromNV[macLoop].bytes[0],
11300 VOS_MAC_ADDR_SIZE);
11301 }
11302 }
11303 }
11304 else
11305 {
11306 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
11307 return VOS_STATUS_E_FAILURE;
11308 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011309
Jeff Johnson295189b2012-06-20 16:38:30 -070011310
11311 return VOS_STATUS_SUCCESS;
11312}
11313
11314/**---------------------------------------------------------------------------
11315
11316 \brief hdd_post_voss_start_config() - HDD post voss start config helper
11317
11318 \param - pAdapter - Pointer to the HDD
11319
11320 \return - None
11321
11322 --------------------------------------------------------------------------*/
11323VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
11324{
11325 eHalStatus halStatus;
11326 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011327 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070011328
Jeff Johnson295189b2012-06-20 16:38:30 -070011329
11330 // Send ready indication to the HDD. This will kick off the MAC
11331 // into a 'running' state and should kick off an initial scan.
11332 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
11333 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11334 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011335 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 "code %08d [x%08x]",__func__, halStatus, halStatus );
11337 return VOS_STATUS_E_FAILURE;
11338 }
11339
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011340 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070011341 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
11342 // And RIVA will crash
11343 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
11344 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011345 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
11346 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
11347
11348
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 return VOS_STATUS_SUCCESS;
11350}
11351
Jeff Johnson295189b2012-06-20 16:38:30 -070011352/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011353void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070011354{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011355
11356 vos_wake_lock_acquire(&wlan_wake_lock, reason);
11357
Jeff Johnson295189b2012-06-20 16:38:30 -070011358}
11359
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011360void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070011361{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011362
11363 vos_wake_lock_release(&wlan_wake_lock, reason);
11364
Jeff Johnson295189b2012-06-20 16:38:30 -070011365}
11366
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011367void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011368{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011369
11370 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
11371 reason);
11372
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011373}
11374
Jeff Johnson295189b2012-06-20 16:38:30 -070011375/**---------------------------------------------------------------------------
11376
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011377 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
11378 information between Host and Riva
11379
11380 This function gets reported version of FW
11381 It also finds the version of Riva headers used to compile the host
11382 It compares the above two and prints a warning if they are different
11383 It gets the SW and HW version string
11384 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
11385 indicating the features they support through a bitmap
11386
11387 \param - pHddCtx - Pointer to HDD context
11388
11389 \return - void
11390
11391 --------------------------------------------------------------------------*/
11392
11393void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
11394{
11395
11396 tSirVersionType versionCompiled;
11397 tSirVersionType versionReported;
11398 tSirVersionString versionString;
11399 tANI_U8 fwFeatCapsMsgSupported = 0;
11400 VOS_STATUS vstatus;
11401
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080011402 memset(&versionCompiled, 0, sizeof(versionCompiled));
11403 memset(&versionReported, 0, sizeof(versionReported));
11404
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011405 /* retrieve and display WCNSS version information */
11406 do {
11407
11408 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
11409 &versionCompiled);
11410 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11411 {
11412 hddLog(VOS_TRACE_LEVEL_FATAL,
11413 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011414 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011415 break;
11416 }
11417
11418 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
11419 &versionReported);
11420 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11421 {
11422 hddLog(VOS_TRACE_LEVEL_FATAL,
11423 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011424 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011425 break;
11426 }
11427
11428 if ((versionCompiled.major != versionReported.major) ||
11429 (versionCompiled.minor != versionReported.minor) ||
11430 (versionCompiled.version != versionReported.version) ||
11431 (versionCompiled.revision != versionReported.revision))
11432 {
11433 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
11434 "Host expected %u.%u.%u.%u\n",
11435 WLAN_MODULE_NAME,
11436 (int)versionReported.major,
11437 (int)versionReported.minor,
11438 (int)versionReported.version,
11439 (int)versionReported.revision,
11440 (int)versionCompiled.major,
11441 (int)versionCompiled.minor,
11442 (int)versionCompiled.version,
11443 (int)versionCompiled.revision);
11444 }
11445 else
11446 {
11447 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
11448 WLAN_MODULE_NAME,
11449 (int)versionReported.major,
11450 (int)versionReported.minor,
11451 (int)versionReported.version,
11452 (int)versionReported.revision);
11453 }
11454
11455 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
11456 versionString,
11457 sizeof(versionString));
11458 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11459 {
11460 hddLog(VOS_TRACE_LEVEL_FATAL,
11461 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011462 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011463 break;
11464 }
11465
11466 pr_info("%s: WCNSS software version %s\n",
11467 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053011468 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011469
11470 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
11471 versionString,
11472 sizeof(versionString));
11473 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11474 {
11475 hddLog(VOS_TRACE_LEVEL_FATAL,
11476 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011477 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011478 break;
11479 }
11480
11481 pr_info("%s: WCNSS hardware version %s\n",
11482 WLAN_MODULE_NAME, versionString);
11483
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011484 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
11485 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011486 send the message only if it the riva is 1.1
11487 minor numbers for different riva branches:
11488 0 -> (1.0)Mainline Build
11489 1 -> (1.1)Mainline Build
11490 2->(1.04) Stability Build
11491 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011492 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011493 ((versionReported.minor>=1) && (versionReported.version>=1)))
11494 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
11495 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011496
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011497 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080011498 {
11499#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
11500 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
11501 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
11502#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070011503 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
11504 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
11505 {
11506 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
11507 }
11508
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011509 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080011510 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011511
11512 } while (0);
11513
11514}
Neelansh Mittaledafed22014-09-04 18:54:39 +053011515void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
11516{
11517 struct sk_buff *skb;
11518 struct nlmsghdr *nlh;
11519 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053011520 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053011521 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011522
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053011523 if (in_interrupt() || irqs_disabled() || in_atomic())
11524 flags = GFP_ATOMIC;
11525
11526 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053011527
11528 if(skb == NULL) {
11529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11530 "%s: alloc_skb failed", __func__);
11531 return;
11532 }
11533
11534 nlh = (struct nlmsghdr *)skb->data;
11535 nlh->nlmsg_pid = 0; /* from kernel */
11536 nlh->nlmsg_flags = 0;
11537 nlh->nlmsg_seq = 0;
11538 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
11539
11540 ani_hdr = NLMSG_DATA(nlh);
11541 ani_hdr->type = type;
11542
11543 switch(type) {
11544 case WLAN_SVC_SAP_RESTART_IND:
11545 ani_hdr->length = 0;
11546 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
11547 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
11548 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053011549 case WLAN_SVC_WLAN_TP_IND:
11550 ani_hdr->length = len;
11551 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
11552 + len));
11553 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11554 memcpy(nl_data, data, len);
11555 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
11556 break;
Bhargav shah23c94942015-10-13 12:48:35 +053011557 case WLAN_MSG_RPS_ENABLE_IND:
11558 ani_hdr->length = len;
11559 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
11560 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11561 memcpy(nl_data, data, len);
11562 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
11563 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011564 default:
11565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11566 "Attempt to send unknown nlink message %d", type);
11567 kfree_skb(skb);
11568 return;
11569 }
11570
11571 nl_srv_bcast(skb);
11572
11573 return;
11574}
11575
Bhargav Shahd0715912015-10-01 18:17:37 +053011576/**
11577 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
11578 * @pHddCtx: Valid Global HDD context pointer
11579 * @rx_packets: Number of RX packet in perticular time
11580 *
11581 * Based on the RX packet this function calculate next value of tcp delack.
11582 * This function compare rx packet value to high and low threshold limit.
11583 *
11584 * Return: void
11585 */
11586void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
11587{
11588 /* average of rx_packets and prev_rx is taken so that
11589 bus width doesnot fluctuate much */
11590 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
11591 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011592
Bhargav Shahd0715912015-10-01 18:17:37 +053011593 pHddCtx->prev_rx = rx_packets;
11594 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
11595 next_rx_level = TP_IND_HIGH;
11596 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
11597 next_rx_level = TP_IND_LOW;
11598
11599 hdd_set_delack_value(pHddCtx, next_rx_level);
11600}
11601
11602#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
11603
11604/**
11605 * hdd_tcp_delack_compute_function() - get link status
11606 * @priv: Valid Global HDD context pointer
11607 *
11608 * This function find number of RX packet during timer life span.
11609 * It request tcp delack with number of RX packet and re-configure delack timer
11610 * for tcpDelAckComputeInterval timer interval.
11611 *
11612 * Return: void
11613 */
11614void hdd_tcp_delack_compute_function(void *priv)
11615{
11616 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
11617 hdd_adapter_t *pAdapter = NULL;
11618 v_U32_t rx_packets = 0;
11619 hdd_adapter_list_node_t *pAdapterNode = NULL;
11620 VOS_STATUS status = 0;
11621
11622 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
11623 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
11624 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
11625 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
11626 continue;
11627
11628 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
11629 pAdapter->prev_rx_packets);
11630 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
11631 }
11632
11633 hdd_request_tcp_delack(pHddCtx, rx_packets);
11634
11635 vos_timer_start(&pHddCtx->delack_timer,
11636 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11637}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011638
11639/**---------------------------------------------------------------------------
11640
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011641 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11642
11643 \param - pHddCtx - Pointer to the hdd context
11644
11645 \return - true if hardware supports 5GHz
11646
11647 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011648boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011649{
11650 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11651 * then hardware support 5Ghz.
11652 */
11653 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11654 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011656 return true;
11657 }
11658 else
11659 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011660 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011661 __func__);
11662 return false;
11663 }
11664}
11665
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011666/**---------------------------------------------------------------------------
11667
11668 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11669 generate function
11670
11671 This is generate the random mac address for WLAN interface
11672
11673 \param - pHddCtx - Pointer to HDD context
11674 idx - Start interface index to get auto
11675 generated mac addr.
11676 mac_addr - Mac address
11677
11678 \return - 0 for success, < 0 for failure
11679
11680 --------------------------------------------------------------------------*/
11681
11682static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11683 int idx, v_MACADDR_t mac_addr)
11684{
11685 int i;
11686 unsigned int serialno;
11687 serialno = wcnss_get_serial_number();
11688
11689 if (0 != serialno)
11690 {
11691 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11692 bytes of the serial number that can be used to generate
11693 the other 3 bytes of the MAC address. Mask off all but
11694 the lower 3 bytes (this will also make sure we don't
11695 overflow in the next step) */
11696 serialno &= 0x00FFFFFF;
11697
11698 /* we need a unique address for each session */
11699 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11700
11701 /* autogen other Mac addresses */
11702 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11703 {
11704 /* start with the entire default address */
11705 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11706 /* then replace the lower 3 bytes */
11707 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11708 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11709 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11710
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053011711 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
11712 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
11713 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
11714 VOS_MAX_CONCURRENCY_PERSONA;
11715
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011716 serialno++;
11717 hddLog(VOS_TRACE_LEVEL_ERROR,
11718 "%s: Derived Mac Addr: "
11719 MAC_ADDRESS_STR, __func__,
11720 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11721 }
11722
11723 }
11724 else
11725 {
11726 hddLog(LOGE, FL("Failed to Get Serial NO"));
11727 return -1;
11728 }
11729 return 0;
11730}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011731
Katya Nigame7b69a82015-04-28 15:24:06 +053011732int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11733{
11734 VOS_STATUS status;
11735 v_CONTEXT_t pVosContext= NULL;
11736 hdd_adapter_t *pAdapter= NULL;
11737
11738 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11739
11740 if (NULL == pVosContext)
11741 {
11742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11743 "%s: Trying to open VOSS without a PreOpen", __func__);
11744 VOS_ASSERT(0);
11745 return VOS_STATUS_E_FAILURE;
11746 }
11747
11748 status = vos_nv_open();
11749 if (!VOS_IS_STATUS_SUCCESS(status))
11750 {
11751 /* NV module cannot be initialized */
11752 hddLog( VOS_TRACE_LEVEL_FATAL,
11753 "%s: vos_nv_open failed", __func__);
11754 return VOS_STATUS_E_FAILURE;
11755 }
11756
11757 status = vos_init_wiphy_from_nv_bin();
11758 if (!VOS_IS_STATUS_SUCCESS(status))
11759 {
11760 /* NV module cannot be initialized */
11761 hddLog( VOS_TRACE_LEVEL_FATAL,
11762 "%s: vos_init_wiphy failed", __func__);
11763 goto err_vos_nv_close;
11764 }
11765
11766 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11767 if ( !VOS_IS_STATUS_SUCCESS( status ))
11768 {
11769 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11770 goto err_vos_nv_close;
11771 }
11772
11773 status = vos_mon_start( pVosContext );
11774 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11775 {
11776 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11777 goto err_vosclose;
11778 }
11779
11780 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11781 WDA_featureCapsExchange(pVosContext);
11782 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11783
11784 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11785 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11786 if( pAdapter == NULL )
11787 {
11788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11789 goto err_close_adapter;
11790 }
11791
11792 //Initialize the nlink service
11793 if(nl_srv_init() != 0)
11794 {
11795 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11796 goto err_close_adapter;
11797 }
11798 return VOS_STATUS_SUCCESS;
11799
11800err_close_adapter:
11801 hdd_close_all_adapters( pHddCtx );
11802 vos_mon_stop( pVosContext );
11803err_vosclose:
11804 status = vos_sched_close( pVosContext );
11805 if (!VOS_IS_STATUS_SUCCESS(status)) {
11806 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11807 "%s: Failed to close VOSS Scheduler", __func__);
11808 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11809 }
11810 vos_close(pVosContext );
11811
11812err_vos_nv_close:
11813 vos_nv_close();
11814
11815return status;
11816}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011817/**---------------------------------------------------------------------------
11818
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011819 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11820 completed to flush out the scan results
11821
11822 11d scan is done during driver load and is a passive scan on all
11823 channels supported by the device, 11d scans may find some APs on
11824 frequencies which are forbidden to be used in the regulatory domain
11825 the device is operating in. If these APs are notified to the supplicant
11826 it may try to connect to these APs, thus flush out all the scan results
11827 which are present in SME after 11d scan is done.
11828
11829 \return - eHalStatus
11830
11831 --------------------------------------------------------------------------*/
11832static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11833 tANI_U32 scanId, eCsrScanStatus status)
11834{
11835 ENTER();
11836
11837 sme_ScanFlushResult(halHandle, 0);
11838
11839 EXIT();
11840
11841 return eHAL_STATUS_SUCCESS;
11842}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011843/**---------------------------------------------------------------------------
11844
11845 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11846 logging is completed successfully.
11847
11848 \return - None
11849
11850 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011851void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011852{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011853 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011854
11855 if (NULL == pHddCtx)
11856 {
11857 hddLog(VOS_TRACE_LEVEL_ERROR,
11858 "%s: HDD context is NULL",__func__);
11859 return;
11860 }
11861
c_manjeecfd1efb2015-09-25 19:32:34 +053011862 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011863 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011864 {
11865 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11866 pHddCtx->mgmt_frame_logging = TRUE;
11867 }
11868 else
11869 {
11870 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11871 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011872 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011873 }
11874
c_manjeecfd1efb2015-09-25 19:32:34 +053011875 /*Check feature supported by FW*/
11876 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11877 {
11878 //Store fwr mem dump size given by firmware.
11879 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11880 }
11881 else
11882 {
11883 wlan_store_fwr_mem_dump_size(0);
11884 }
11885
11886
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011887}
11888/**---------------------------------------------------------------------------
11889
11890 \brief hdd_init_frame_logging - function to initialize frame logging.
11891 Currently only Mgmt Frames are logged in both TX
11892 and Rx direction and are sent to userspace
11893 application using logger thread when queried.
11894
11895 \return - None
11896
11897 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011898void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011899{
11900 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011901 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011902
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011903 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11904 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011905 {
11906 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11907 return;
11908 }
11909
c_manjeecfd1efb2015-09-25 19:32:34 +053011910 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011911 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11912 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011913 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11914 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011915
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011916 if (pHddCtx->cfg_ini->enableFWLogging ||
11917 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011918 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011919 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011920 }
11921
Sushant Kaushik46804902015-07-08 14:46:03 +053011922 if (pHddCtx->cfg_ini->enableMgmtLogging)
11923 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011924 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011925 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011926 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11927 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011928 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011929 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011930 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11931 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11932 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011933 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011934 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011935 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011936 {
11937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11938 return;
11939 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011940 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11941 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11942 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11943 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011944 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011945
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011946 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011947
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011948 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011949 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011950 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011951 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011952 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11953 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011954
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011955 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011956
11957 if (eHAL_STATUS_SUCCESS != halStatus)
11958 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011959 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11960 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011961 }
11962
11963 return;
11964}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011965
Bhargav shah23c94942015-10-13 12:48:35 +053011966static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11967{
11968 hdd_adapter_t *adapter;
11969 hdd_adapter_list_node_t *adapter_node, *next;
11970 VOS_STATUS status = VOS_STATUS_SUCCESS;
11971 struct wlan_rps_data rps_data;
11972 int count;
11973
11974 if(!hdd_ctxt->cfg_ini->rps_mask)
11975 {
11976 return;
11977 }
11978
11979 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11980 {
11981 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11982 }
11983
11984 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11985
11986 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11987 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11988 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11989
11990 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11991
11992 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11993 {
11994 adapter = adapter_node->pAdapter;
11995 if (NULL != adapter) {
11996 strlcpy(rps_data.ifname, adapter->dev->name,
11997 sizeof(rps_data.ifname));
11998 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11999 (void *)&rps_data,sizeof(rps_data));
12000 }
12001 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
12002 adapter_node = next;
12003 }
12004}
12005
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012006void wlan_hdd_schedule_defer_scan(struct work_struct *work)
12007{
12008 scan_context_t *scan_ctx =
12009 container_of(work, scan_context_t, scan_work.work);
12010
12011 if (NULL == scan_ctx)
12012 {
12013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12014 FL("scan_ctx is NULL"));
12015 return;
12016 }
12017
12018 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
12019 return;
12020
12021 scan_ctx->attempt++;
12022
12023 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
12024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12025 scan_ctx->dev,
12026#endif
12027 scan_ctx->scan_request);
12028}
12029
12030int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
12031 struct wiphy *wiphy,
12032#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12033 struct net_device *dev,
12034#endif
12035 struct cfg80211_scan_request *request)
12036{
12037 scan_context_t *scan_ctx;
12038
12039 ENTER();
12040 if (0 != (wlan_hdd_validate_context(pHddCtx)))
12041 {
12042 return -1;
12043 }
12044
12045 scan_ctx = &pHddCtx->scan_ctxt;
12046
12047 scan_ctx->wiphy = wiphy;
12048#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12049 scan_ctx->dev = dev;
12050#endif
12051
12052 scan_ctx->scan_request = request;
12053
12054 EXIT();
12055 return 0;
12056}
12057
12058void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
12059 struct wiphy *wiphy,
12060#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12061 struct net_device *dev,
12062#endif
12063 struct cfg80211_scan_request *request,
12064 unsigned long delay)
12065{
12066 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
12067 {
12068#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12069 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
12070#else
12071 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
12072#endif
12073 pHddCtx->scan_ctxt.attempt = 0;
12074 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
12075 }
12076 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
12077}
12078
12079void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
12080{
12081 scan_ctx->magic = 0;
12082 scan_ctx->attempt = 0;
12083 scan_ctx->reject = 0;
12084 scan_ctx->scan_request = NULL;
12085
12086 return;
12087}
12088
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012089/**---------------------------------------------------------------------------
12090
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 \brief hdd_wlan_startup() - HDD init function
12092
12093 This is the driver startup code executed once a WLAN device has been detected
12094
12095 \param - dev - Pointer to the underlying device
12096
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012097 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070012098
12099 --------------------------------------------------------------------------*/
12100
12101int hdd_wlan_startup(struct device *dev )
12102{
12103 VOS_STATUS status;
12104 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012105 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 hdd_context_t *pHddCtx = NULL;
12107 v_CONTEXT_t pVosContext= NULL;
12108#ifdef WLAN_BTAMP_FEATURE
12109 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
12110 WLANBAP_ConfigType btAmpConfig;
12111 hdd_config_t *pConfig;
12112#endif
12113 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012115 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012116
12117 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 /*
12119 * cfg80211: wiphy allocation
12120 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012121 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012122
12123 if(wiphy == NULL)
12124 {
12125 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012126 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012127 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 pHddCtx = wiphy_priv(wiphy);
12129
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 //Initialize the adapter context to zeros.
12131 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
12132
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012134 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053012135 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012136
12137 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12138
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012139 /* register for riva power on lock to platform driver
12140 * Locking power early to ensure FW doesn't reset by kernel while
12141 * host driver is busy initializing itself */
12142 if (req_riva_power_on_lock("wlan"))
12143 {
12144 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
12145 __func__);
12146 goto err_free_hdd_context;
12147 }
12148
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 /*Get vos context here bcoz vos_open requires it*/
12150 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12151
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080012152 if(pVosContext == NULL)
12153 {
12154 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
12155 goto err_free_hdd_context;
12156 }
12157
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 //Save the Global VOSS context in adapter context for future.
12159 pHddCtx->pvosContext = pVosContext;
12160
12161 //Save the adapter context in global context for future.
12162 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
12163
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053012165 pHddCtx->last_scan_reject_session_id = 0xFF;
12166 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053012167 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053012168 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012169
12170 init_completion(&pHddCtx->full_pwr_comp_var);
12171 init_completion(&pHddCtx->standby_comp_var);
12172 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012173 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012174 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053012175 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012176 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012177 init_completion(&pHddCtx->mc_sus_event_var);
12178 init_completion(&pHddCtx->tx_sus_event_var);
12179 init_completion(&pHddCtx->rx_sus_event_var);
12180
Amar Singhala49cbc52013-10-08 18:37:44 -070012181
mukul sharma4bd8d2e2015-08-13 20:33:25 +053012182 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053012183 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053012184
Amar Singhala49cbc52013-10-08 18:37:44 -070012185#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070012186 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070012187#else
12188 init_completion(&pHddCtx->driver_crda_req);
12189#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012190
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053012191#ifdef WLAN_FEATURE_EXTSCAN
12192 init_completion(&pHddCtx->ext_scan_context.response_event);
12193#endif /* WLAN_FEATURE_EXTSCAN */
12194
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012195 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053012196 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012197
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
12199
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012200 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
12201 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053012202 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012203 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
12204 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012205
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012206#ifdef FEATURE_WLAN_TDLS
12207 /* tdls_lock is initialized before an hdd_open_adapter ( which is
12208 * invoked by other instances also) to protect the concurrent
12209 * access for the Adapters by TDLS module.
12210 */
12211 mutex_init(&pHddCtx->tdls_lock);
12212#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053012213 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053012214 mutex_init(&pHddCtx->wmmLock);
12215
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053012216 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053012217 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012218
Agarwal Ashish1f422872014-07-22 00:11:55 +053012219 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 // Load all config first as TL config is needed during vos_open
12221 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
12222 if(pHddCtx->cfg_ini == NULL)
12223 {
12224 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
12225 goto err_free_hdd_context;
12226 }
12227
12228 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
12229
12230 // Read and parse the qcom_cfg.ini file
12231 status = hdd_parse_config_ini( pHddCtx );
12232 if ( VOS_STATUS_SUCCESS != status )
12233 {
12234 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
12235 __func__, WLAN_INI_FILE);
12236 goto err_config;
12237 }
Arif Hussaind5218912013-12-05 01:10:55 -080012238#ifdef MEMORY_DEBUG
12239 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
12240 vos_mem_init();
12241
12242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
12243 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
12244#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012245
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053012246 /* INI has been read, initialise the configuredMcastBcastFilter with
12247 * INI value as this will serve as the default value
12248 */
12249 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
12250 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
12251 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012252
12253 if (false == hdd_is_5g_supported(pHddCtx))
12254 {
12255 //5Ghz is not supported.
12256 if (1 != pHddCtx->cfg_ini->nBandCapability)
12257 {
12258 hddLog(VOS_TRACE_LEVEL_INFO,
12259 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
12260 pHddCtx->cfg_ini->nBandCapability = 1;
12261 }
12262 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053012263
12264 /* If SNR Monitoring is enabled, FW has to parse all beacons
12265 * for calcaluting and storing the average SNR, so set Nth beacon
12266 * filter to 1 to enable FW to parse all the beaocons
12267 */
12268 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
12269 {
12270 /* The log level is deliberately set to WARN as overriding
12271 * nthBeaconFilter to 1 will increase power cosumption and this
12272 * might just prove helpful to detect the power issue.
12273 */
12274 hddLog(VOS_TRACE_LEVEL_WARN,
12275 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
12276 pHddCtx->cfg_ini->nthBeaconFilter = 1;
12277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012279 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053012281 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053012283 hddLog(VOS_TRACE_LEVEL_FATAL,
12284 "%s: wlan_hdd_cfg80211_init return failure", __func__);
12285 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012287
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080012288 // Update VOS trace levels based upon the cfg.ini
12289 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
12290 pHddCtx->cfg_ini->vosTraceEnableBAP);
12291 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
12292 pHddCtx->cfg_ini->vosTraceEnableTL);
12293 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
12294 pHddCtx->cfg_ini->vosTraceEnableWDI);
12295 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
12296 pHddCtx->cfg_ini->vosTraceEnableHDD);
12297 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
12298 pHddCtx->cfg_ini->vosTraceEnableSME);
12299 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
12300 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053012301 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
12302 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080012303 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
12304 pHddCtx->cfg_ini->vosTraceEnableWDA);
12305 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
12306 pHddCtx->cfg_ini->vosTraceEnableSYS);
12307 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
12308 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080012309 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
12310 pHddCtx->cfg_ini->vosTraceEnableSAP);
12311 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
12312 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080012313
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 // Update WDI trace levels based upon the cfg.ini
12315 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
12316 pHddCtx->cfg_ini->wdiTraceEnableDAL);
12317 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
12318 pHddCtx->cfg_ini->wdiTraceEnableCTL);
12319 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
12320 pHddCtx->cfg_ini->wdiTraceEnableDAT);
12321 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
12322 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070012323
Jeff Johnson88ba7742013-02-27 14:36:02 -080012324 if (VOS_FTM_MODE == hdd_get_conparam())
12325 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
12327 {
12328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
12329 goto err_free_hdd_context;
12330 }
12331 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053012332 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053012333 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080012335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012336
Katya Nigame7b69a82015-04-28 15:24:06 +053012337 if( VOS_MONITOR_MODE == hdd_get_conparam())
12338 {
12339 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
12340 {
12341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
12342 goto err_free_hdd_context;
12343 }
12344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
12345 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
12346 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
12347 return VOS_STATUS_SUCCESS;
12348 }
12349
Jeff Johnson88ba7742013-02-27 14:36:02 -080012350 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12352 {
12353 status = vos_watchdog_open(pVosContext,
12354 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
12355
12356 if(!VOS_IS_STATUS_SUCCESS( status ))
12357 {
12358 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053012359 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070012360 }
12361 }
12362
12363 pHddCtx->isLogpInProgress = FALSE;
12364 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
12365
Amar Singhala49cbc52013-10-08 18:37:44 -070012366#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012367 /* initialize the NV module. This is required so that
12368 we can initialize the channel information in wiphy
12369 from the NV.bin data. The channel information in
12370 wiphy needs to be initialized before wiphy registration */
12371
12372 status = vos_nv_open();
12373 if (!VOS_IS_STATUS_SUCCESS(status))
12374 {
12375 /* NV module cannot be initialized */
12376 hddLog( VOS_TRACE_LEVEL_FATAL,
12377 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053012378 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070012379 }
12380
12381 status = vos_init_wiphy_from_nv_bin();
12382 if (!VOS_IS_STATUS_SUCCESS(status))
12383 {
12384 /* NV module cannot be initialized */
12385 hddLog( VOS_TRACE_LEVEL_FATAL,
12386 "%s: vos_init_wiphy failed", __func__);
12387 goto err_vos_nv_close;
12388 }
12389
Amar Singhala49cbc52013-10-08 18:37:44 -070012390#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012391 //Initialize the nlink service
12392 if(nl_srv_init() != 0)
12393 {
12394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
12395 goto err_vos_nv_close;
12396 }
12397
12398#ifdef WLAN_KD_READY_NOTIFIER
12399 pHddCtx->kd_nl_init = 1;
12400#endif /* WLAN_KD_READY_NOTIFIER */
12401
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053012402 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053012403 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 if ( !VOS_IS_STATUS_SUCCESS( status ))
12405 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012406 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012407 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 }
12409
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
12411
12412 if ( NULL == pHddCtx->hHal )
12413 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012414 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012415 goto err_vosclose;
12416 }
12417
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012418 status = vos_preStart( pHddCtx->pvosContext );
12419 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12420 {
12421 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012422 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012423 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012424
Arif Hussaineaf68602013-12-30 23:10:44 -080012425 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
12426 {
12427 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
12428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
12429 __func__, enable_dfs_chan_scan);
12430 }
12431 if (0 == enable_11d || 1 == enable_11d)
12432 {
12433 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
12434 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
12435 __func__, enable_11d);
12436 }
12437
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012438 /* Note that the vos_preStart() sequence triggers the cfg download.
12439 The cfg download must occur before we update the SME config
12440 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 status = hdd_set_sme_config( pHddCtx );
12442
12443 if ( VOS_STATUS_SUCCESS != status )
12444 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012445 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012446 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012447 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012448
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 /* In the integrated architecture we update the configuration from
12450 the INI file and from NV before vOSS has been started so that
12451 the final contents are available to send down to the cCPU */
12452
12453 // Apply the cfg.ini to cfg.dat
12454 if (FALSE == hdd_update_config_dat(pHddCtx))
12455 {
12456 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012457 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 }
12459
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012460 // Get mac addr from platform driver
12461 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
12462
12463 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012465 /* Store the mac addr for first interface */
12466 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
12467
12468 hddLog(VOS_TRACE_LEVEL_ERROR,
12469 "%s: WLAN Mac Addr: "
12470 MAC_ADDRESS_STR, __func__,
12471 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
12472
12473 /* Here, passing Arg2 as 1 because we do not want to change the
12474 last 3 bytes (means non OUI bytes) of first interface mac
12475 addr.
12476 */
12477 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
12478 {
12479 hddLog(VOS_TRACE_LEVEL_ERROR,
12480 "%s: Failed to generate wlan interface mac addr "
12481 "using MAC from ini file ", __func__);
12482 }
12483 }
12484 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
12485 {
12486 // Apply the NV to cfg.dat
12487 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070012488#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
12489 /* There was not a valid set of MAC Addresses in NV. See if the
12490 default addresses were modified by the cfg.ini settings. If so,
12491 we'll use them, but if not, we'll autogenerate a set of MAC
12492 addresses based upon the device serial number */
12493
12494 static const v_MACADDR_t default_address =
12495 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070012496
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012497 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
12498 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012499 {
12500 /* cfg.ini has the default address, invoke autogen logic */
12501
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012502 /* Here, passing Arg2 as 0 because we want to change the
12503 last 3 bytes (means non OUI bytes) of all the interfaces
12504 mac addr.
12505 */
12506 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
12507 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012509 hddLog(VOS_TRACE_LEVEL_ERROR,
12510 "%s: Failed to generate wlan interface mac addr "
12511 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
12512 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070012513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 }
12515 else
12516#endif //WLAN_AUTOGEN_MACADDR_FEATURE
12517 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012518 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 "%s: Invalid MAC address in NV, using MAC from ini file "
12520 MAC_ADDRESS_STR, __func__,
12521 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
12522 }
12523 }
12524 {
12525 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012526
12527 /* Set the MAC Address Currently this is used by HAL to
12528 * add self sta. Remove this once self sta is added as
12529 * part of session open.
12530 */
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
12532 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
12533 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012534
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 if (!HAL_STATUS_SUCCESS( halStatus ))
12536 {
12537 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
12538 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012539 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 }
12541 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012542
12543 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
12544 Note: Firmware image will be read and downloaded inside vos_start API */
12545 status = vos_start( pHddCtx->pvosContext );
12546 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12547 {
12548 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012549 if (isSsrPanicOnFailure())
12550 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012551 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 }
12553
Leo Chang6cec3e22014-01-21 15:33:49 -080012554#ifdef FEATURE_WLAN_CH_AVOID
12555 /* Plug in avoid channel notification callback
12556 * This should happen before ADD_SELF_STA
12557 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053012558
12559 /* check the Channel Avoidance is enabled */
12560 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
12561 {
12562 sme_AddChAvoidCallback(pHddCtx->hHal,
12563 hdd_hostapd_ch_avoid_cb);
12564 }
Leo Chang6cec3e22014-01-21 15:33:49 -080012565#endif /* FEATURE_WLAN_CH_AVOID */
12566
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012567 /* Exchange capability info between Host and FW and also get versioning info from FW */
12568 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012569
Agarwal Ashishad9281b2014-06-10 14:57:30 +053012570#ifdef CONFIG_ENABLE_LINUX_REG
12571 status = wlan_hdd_init_channels(pHddCtx);
12572 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12573 {
12574 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
12575 __func__);
12576 goto err_vosstop;
12577 }
12578#endif
12579
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 status = hdd_post_voss_start_config( pHddCtx );
12581 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12582 {
12583 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
12584 __func__);
12585 goto err_vosstop;
12586 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012587
12588#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012589 wlan_hdd_cfg80211_update_reg_info( wiphy );
12590
12591 /* registration of wiphy dev with cfg80211 */
12592 if (0 > wlan_hdd_cfg80211_register(wiphy))
12593 {
12594 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
12595 goto err_vosstop;
12596 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012597#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012598
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012599#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012600 /* registration of wiphy dev with cfg80211 */
12601 if (0 > wlan_hdd_cfg80211_register(wiphy))
12602 {
12603 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
12604 goto err_vosstop;
12605 }
12606
Agarwal Ashish6db9d532014-09-30 18:19:10 +053012607 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012608 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12609 {
12610 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
12611 __func__);
12612 goto err_unregister_wiphy;
12613 }
12614#endif
12615
c_hpothu4a298be2014-12-22 21:12:51 +053012616 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
12617
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 if (VOS_STA_SAP_MODE == hdd_get_conparam())
12619 {
12620 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
12621 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12622 }
12623 else
12624 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
12626 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12627 if (pAdapter != NULL)
12628 {
Katya Nigama7d81d72014-11-12 12:44:34 +053012629 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012631 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
12632 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
12633 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070012634
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012635 /* Generate the P2P Device Address. This consists of the device's
12636 * primary MAC address with the locally administered bit set.
12637 */
12638 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070012639 }
12640 else
12641 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012642 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
12643 if (p2p_dev_addr != NULL)
12644 {
12645 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
12646 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
12647 }
12648 else
12649 {
12650 hddLog(VOS_TRACE_LEVEL_FATAL,
12651 "%s: Failed to allocate mac_address for p2p_device",
12652 __func__);
12653 goto err_close_adapter;
12654 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012655 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012656
12657 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12658 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12659 if ( NULL == pP2pAdapter )
12660 {
12661 hddLog(VOS_TRACE_LEVEL_FATAL,
12662 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012663 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012664 goto err_close_adapter;
12665 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012666 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012668
12669 if( pAdapter == NULL )
12670 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12672 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012674
Arif Hussain66559122013-11-21 10:11:40 -080012675 if (country_code)
12676 {
12677 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012678 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012679 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12680#ifndef CONFIG_ENABLE_LINUX_REG
12681 hdd_checkandupdate_phymode(pAdapter, country_code);
12682#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012683 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12684 (void *)(tSmeChangeCountryCallback)
12685 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012686 country_code,
12687 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012688 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012689 if (eHAL_STATUS_SUCCESS == ret)
12690 {
Arif Hussaincb607082013-12-20 11:57:42 -080012691 ret = wait_for_completion_interruptible_timeout(
12692 &pAdapter->change_country_code,
12693 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12694
12695 if (0 >= ret)
12696 {
12697 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12698 "%s: SME while setting country code timed out", __func__);
12699 }
Arif Hussain66559122013-11-21 10:11:40 -080012700 }
12701 else
12702 {
Arif Hussaincb607082013-12-20 11:57:42 -080012703 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12704 "%s: SME Change Country code from module param fail ret=%d",
12705 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012706 }
12707 }
12708
Jeff Johnson295189b2012-06-20 16:38:30 -070012709#ifdef WLAN_BTAMP_FEATURE
12710 vStatus = WLANBAP_Open(pVosContext);
12711 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12712 {
12713 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12714 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012715 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 }
12717
12718 vStatus = BSL_Init(pVosContext);
12719 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12720 {
12721 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12722 "%s: Failed to Init BSL",__func__);
12723 goto err_bap_close;
12724 }
12725 vStatus = WLANBAP_Start(pVosContext);
12726 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12727 {
12728 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12729 "%s: Failed to start TL",__func__);
12730 goto err_bap_close;
12731 }
12732
12733 pConfig = pHddCtx->cfg_ini;
12734 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12735 status = WLANBAP_SetConfig(&btAmpConfig);
12736
12737#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012738
Mihir Shete9c238772014-10-15 14:35:16 +053012739 /*
12740 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12741 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12742 * which is greater than 0xf. So the below check is safe to make
12743 * sure that there is no entry for UapsdMask in the ini
12744 */
12745 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12746 {
12747 if(IS_DYNAMIC_WMM_PS_ENABLED)
12748 {
12749 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12750 __func__);
12751 pHddCtx->cfg_ini->UapsdMask =
12752 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12753 }
12754 else
12755 {
12756 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12757 __func__);
12758 pHddCtx->cfg_ini->UapsdMask =
12759 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12760 }
12761 }
12762
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012763#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12764 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12765 {
12766 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12767 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12768 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12769 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12770 }
12771#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012772
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012773 wlan_hdd_tdls_init(pHddCtx);
12774
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012775 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12776
12777 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12778 wlan_hdd_schedule_defer_scan);
12779
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012780 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12781
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 /* Register with platform driver as client for Suspend/Resume */
12783 status = hddRegisterPmOps(pHddCtx);
12784 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12785 {
12786 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12787#ifdef WLAN_BTAMP_FEATURE
12788 goto err_bap_stop;
12789#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012790 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012791#endif //WLAN_BTAMP_FEATURE
12792 }
12793
Yue Ma0d4891e2013-08-06 17:01:45 -070012794 /* Open debugfs interface */
12795 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12796 {
12797 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12798 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012799 }
12800
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 /* Register TM level change handler function to the platform */
12802 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12803 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12804 {
12805 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12806 goto err_unregister_pmops;
12807 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012808
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 // register net device notifier for device change notification
12810 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12811
12812 if(ret < 0)
12813 {
12814 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012815 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012816 }
12817
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 //Initialize the BTC service
12819 if(btc_activate_service(pHddCtx) != 0)
12820 {
12821 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012822 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012823 }
12824
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012825#ifdef FEATURE_OEM_DATA_SUPPORT
12826 //Initialize the OEM service
12827 if (oem_activate_service(pHddCtx) != 0)
12828 {
12829 hddLog(VOS_TRACE_LEVEL_FATAL,
12830 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053012831 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012832 }
12833#endif
12834
Jeff Johnson295189b2012-06-20 16:38:30 -070012835#ifdef PTT_SOCK_SVC_ENABLE
12836 //Initialize the PTT service
12837 if(ptt_sock_activate_svc(pHddCtx) != 0)
12838 {
12839 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053012840 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 }
12842#endif
12843
Abhishek Singh00b71972016-01-07 10:51:04 +053012844#ifdef WLAN_FEATURE_RMC
12845 if (hdd_open_cesium_nl_sock() < 0)
12846 {
12847 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053012848 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053012849 }
12850#endif
12851
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012852#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12853 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12854 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012855 if(wlan_logging_sock_activate_svc(
12856 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012857 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12858 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12859 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012860 {
12861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12862 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053012863 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012864 }
12865 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12866 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012867 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12868 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012869 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12870 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012871 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012872
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012873 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12874 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012875 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012876 pHddCtx->cfg_ini->enableContFWLogging ||
12877 pHddCtx->cfg_ini->enableFwrMemDump )
12878 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012879 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012880 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012881 }
12882 else
12883 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012884 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012885 }
12886
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012887#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012888
Agrawal Ashish17ef5082016-10-17 18:33:21 +053012889#ifdef SAP_AUTH_OFFLOAD
12890 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
12891 {
12892 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
12893 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
12894 }
12895#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012896
Sushant Kaushik215778f2015-05-21 14:05:36 +053012897 if (vos_is_multicast_logging())
12898 wlan_logging_set_log_level();
12899
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012903 /* Action frame registered in one adapter which will
12904 * applicable to all interfaces
12905 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012906 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012908
12909 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012910 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012911
Jeff Johnsone7245742012-09-05 17:12:55 -070012912#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12913 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012914 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012915 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012916
Jeff Johnsone7245742012-09-05 17:12:55 -070012917#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012918 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012919 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012920 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012921
Jeff Johnsone7245742012-09-05 17:12:55 -070012922
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012923 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12924 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012925
Katya Nigam5c306ea2014-06-19 15:39:54 +053012926 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012927 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012928 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012929
12930#ifdef FEATURE_WLAN_SCAN_PNO
12931 /*SME must send channel update configuration to RIVA*/
12932 sme_UpdateChannelConfig(pHddCtx->hHal);
12933#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012934 /* Send the update default channel list to the FW*/
12935 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012936
12937 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012938 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12939 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012940 sme_SetDefDot11Mode(pHddCtx->hHal);
12941
Abhishek Singha306a442013-11-07 18:39:01 +053012942#ifndef CONFIG_ENABLE_LINUX_REG
12943 /*updating wiphy so that regulatory user hints can be processed*/
12944 if (wiphy)
12945 {
12946 regulatory_hint(wiphy, "00");
12947 }
12948#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012949 // Initialize the restart logic
12950 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012951
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053012952 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
12953 vos_wdthread_init_timer_work(vos_process_wd_timer);
12954 /* Initialize the timer to detect thread stuck issues */
12955 vos_thread_stuck_timer_init(
12956 &((VosContextType*)pVosContext)->vosWatchdog);
12957 }
12958
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012959 //Register the traffic monitor timer now
12960 if ( pHddCtx->cfg_ini->dynSplitscan)
12961 {
12962 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12963 VOS_TIMER_TYPE_SW,
12964 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12965 (void *)pHddCtx);
12966 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012967 wlan_hdd_cfg80211_nan_init(pHddCtx);
12968
Bhargav Shahd0715912015-10-01 18:17:37 +053012969 mutex_init(&pHddCtx->cur_rx_level_lock);
12970 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12971 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012972 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12973 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012974
Dino Mycle6fb96c12014-06-10 11:52:40 +053012975#ifdef WLAN_FEATURE_EXTSCAN
12976 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12977 wlan_hdd_cfg80211_extscan_callback,
12978 pHddCtx);
12979#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012980
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012981#ifdef FEATURE_OEM_DATA_SUPPORT
12982 sme_OemDataRegisterCallback(pHddCtx->hHal,
12983 wlan_hdd_cfg80211_oemdata_callback,
12984 pHddCtx);
12985#endif /* FEATURE_OEM_DATA_SUPPORT */
12986
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012987 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012988#ifdef WLAN_NS_OFFLOAD
12989 // Register IPv6 notifier to notify if any change in IP
12990 // So that we can reconfigure the offload parameters
12991 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12992 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12993 if (ret)
12994 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012996 }
12997 else
12998 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013000 }
13001#endif
13002
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053013003 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
13004
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013005 // Register IPv4 notifier to notify if any change in IP
13006 // So that we can reconfigure the offload parameters
13007 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
13008 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
13009 if (ret)
13010 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013012 }
13013 else
13014 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013015 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013016 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013017 /*Fw mem dump procfs initialization*/
13018 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053013019 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013020
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053013021 pHddCtx->is_ap_mode_wow_supported =
13022 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053013023
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053013024 pHddCtx->is_fatal_event_log_sup =
13025 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
13026 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
13027 pHddCtx->is_fatal_event_log_sup);
13028
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053013029 hdd_assoc_registerFwdEapolCB(pVosContext);
13030
Jeff Johnson295189b2012-06-20 16:38:30 -070013031 goto success;
13032
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013033err_open_cesium_nl_sock:
13034#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13035 hdd_close_cesium_nl_sock();
13036#endif
13037
13038err_ptt_sock_activate_svc:
13039#ifdef PTT_SOCK_SVC_ENABLE
13040 ptt_sock_deactivate_svc(pHddCtx);
13041#endif
13042
13043err_oem_activate_service:
13044#ifdef FEATURE_OEM_DATA_SUPPORT
13045 oem_deactivate_service();
13046#endif
13047
13048err_btc_activate_service:
13049 btc_deactivate_service();
13050
Jeff Johnson295189b2012-06-20 16:38:30 -070013051err_reg_netdev:
13052 unregister_netdevice_notifier(&hdd_netdev_notifier);
13053
Jeff Johnson295189b2012-06-20 16:38:30 -070013054err_unregister_pmops:
13055 hddDevTmUnregisterNotifyCallback(pHddCtx);
13056 hddDeregisterPmOps(pHddCtx);
13057
Yue Ma0d4891e2013-08-06 17:01:45 -070013058 hdd_debugfs_exit(pHddCtx);
13059
Jeff Johnson295189b2012-06-20 16:38:30 -070013060#ifdef WLAN_BTAMP_FEATURE
13061err_bap_stop:
13062 WLANBAP_Stop(pVosContext);
13063#endif
13064
13065#ifdef WLAN_BTAMP_FEATURE
13066err_bap_close:
13067 WLANBAP_Close(pVosContext);
13068#endif
13069
Jeff Johnson295189b2012-06-20 16:38:30 -070013070err_close_adapter:
13071 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053013072#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013073err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053013074#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013075 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053013076 hdd_wlan_free_wiphy_channels(wiphy);
13077
Jeff Johnson295189b2012-06-20 16:38:30 -070013078err_vosstop:
13079 vos_stop(pVosContext);
13080
Amar Singhala49cbc52013-10-08 18:37:44 -070013081err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 status = vos_sched_close( pVosContext );
13083 if (!VOS_IS_STATUS_SUCCESS(status)) {
13084 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13085 "%s: Failed to close VOSS Scheduler", __func__);
13086 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13087 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013088 vos_close(pVosContext );
13089
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013090err_nl_srv:
13091#ifdef WLAN_KD_READY_NOTIFIER
13092 nl_srv_exit(pHddCtx->ptt_pid);
13093#else
13094 nl_srv_exit();
13095#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070013096err_vos_nv_close:
13097
c_hpothue6a36282014-03-19 12:27:38 +053013098#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013099 vos_nv_close();
13100
c_hpothu70f8d812014-03-22 22:59:23 +053013101#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013102
13103err_wdclose:
13104 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13105 vos_watchdog_close(pVosContext);
13106
Jeff Johnson295189b2012-06-20 16:38:30 -070013107err_config:
13108 kfree(pHddCtx->cfg_ini);
13109 pHddCtx->cfg_ini= NULL;
13110
13111err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013112 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013113 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 wiphy_free(wiphy) ;
13115 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 VOS_BUG(1);
13117
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080013118 if (hdd_is_ssr_required())
13119 {
13120 /* WDI timeout had happened during load, so SSR is needed here */
13121 subsystem_restart("wcnss");
13122 msleep(5000);
13123 }
13124 hdd_set_ssr_required (VOS_FALSE);
13125
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013126 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013127
13128success:
13129 EXIT();
13130 return 0;
13131}
13132
13133/**---------------------------------------------------------------------------
13134
Jeff Johnson32d95a32012-09-10 13:15:23 -070013135 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070013136
Jeff Johnson32d95a32012-09-10 13:15:23 -070013137 This is the driver entry point - called in different timeline depending
13138 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070013139
13140 \param - None
13141
13142 \return - 0 for success, non zero for failure
13143
13144 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070013145static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070013146{
13147 VOS_STATUS status;
13148 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 struct device *dev = NULL;
13150 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013151#ifdef HAVE_WCNSS_CAL_DOWNLOAD
13152 int max_retries = 0;
13153#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013154#ifdef HAVE_CBC_DONE
13155 int max_cbc_retries = 0;
13156#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013157
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013158#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13159 wlan_logging_sock_init_svc();
13160#endif
13161
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 ENTER();
13163
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013164 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070013165
13166 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
13167 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
13168
Jeff Johnson295189b2012-06-20 16:38:30 -070013169#ifdef ANI_BUS_TYPE_PCI
13170
13171 dev = wcnss_wlan_get_device();
13172
13173#endif // ANI_BUS_TYPE_PCI
13174
13175#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013176
13177#ifdef HAVE_WCNSS_CAL_DOWNLOAD
13178 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053013179 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013180 msleep(1000);
13181 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013182
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053013183 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013184 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013185 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013186#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13187 wlan_logging_sock_deinit_svc();
13188#endif
13189
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013190 return -ENODEV;
13191 }
13192#endif
13193
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013194#ifdef HAVE_CBC_DONE
13195 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
13196 msleep(1000);
13197 }
13198 if (max_cbc_retries >= 10) {
13199 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
13200 }
13201#endif
13202
Jeff Johnson295189b2012-06-20 16:38:30 -070013203 dev = wcnss_wlan_get_device();
13204#endif // ANI_BUS_TYPE_PLATFORM
13205
13206
13207 do {
13208 if (NULL == dev) {
13209 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
13210 ret_status = -1;
13211 break;
13212 }
13213
Jeff Johnson295189b2012-06-20 16:38:30 -070013214#ifdef TIMER_MANAGER
13215 vos_timer_manager_init();
13216#endif
13217
13218 /* Preopen VOSS so that it is ready to start at least SAL */
13219 status = vos_preOpen(&pVosContext);
13220
13221 if (!VOS_IS_STATUS_SUCCESS(status))
13222 {
13223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
13224 ret_status = -1;
13225 break;
13226 }
13227
Sushant Kaushik02beb352015-06-04 15:15:01 +053013228 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053013229 hdd_register_debug_callback();
13230
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013231#ifndef MODULE
13232 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
13233 */
13234 hdd_set_conparam((v_UINT_t)con_mode);
13235#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013236
13237 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013238 if (hdd_wlan_startup(dev))
13239 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013240 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013241 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 vos_preClose( &pVosContext );
13243 ret_status = -1;
13244 break;
13245 }
13246
Jeff Johnson295189b2012-06-20 16:38:30 -070013247 } while (0);
13248
13249 if (0 != ret_status)
13250 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013251#ifdef TIMER_MANAGER
13252 vos_timer_exit();
13253#endif
13254#ifdef MEMORY_DEBUG
13255 vos_mem_exit();
13256#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013257 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013258#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13259 wlan_logging_sock_deinit_svc();
13260#endif
13261
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
13263 }
13264 else
13265 {
13266 //Send WLAN UP indication to Nlink Service
13267 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
13268
13269 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 }
13271
13272 EXIT();
13273
13274 return ret_status;
13275}
13276
Jeff Johnson32d95a32012-09-10 13:15:23 -070013277/**---------------------------------------------------------------------------
13278
13279 \brief hdd_module_init() - Init Function
13280
13281 This is the driver entry point (invoked when module is loaded using insmod)
13282
13283 \param - None
13284
13285 \return - 0 for success, non zero for failure
13286
13287 --------------------------------------------------------------------------*/
13288#ifdef MODULE
13289static int __init hdd_module_init ( void)
13290{
13291 return hdd_driver_init();
13292}
Jeff Johnson32d95a32012-09-10 13:15:23 -070013293#else /* #ifdef MODULE */
13294static int __init hdd_module_init ( void)
13295{
13296 /* Driver initialization is delayed to fwpath_changed_handler */
13297 return 0;
13298}
Jeff Johnson32d95a32012-09-10 13:15:23 -070013299#endif /* #ifdef MODULE */
13300
Jeff Johnson295189b2012-06-20 16:38:30 -070013301
13302/**---------------------------------------------------------------------------
13303
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013304 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070013305
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013306 This is the driver exit point (invoked when module is unloaded using rmmod
13307 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070013308
13309 \param - None
13310
13311 \return - None
13312
13313 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013314static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070013315{
13316 hdd_context_t *pHddCtx = NULL;
13317 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053013318 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013319 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013320
13321 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
13322
13323 //Get the global vos context
13324 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13325
13326 if(!pVosContext)
13327 {
13328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
13329 goto done;
13330 }
13331
13332 //Get the HDD context.
13333 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
13334
13335 if(!pHddCtx)
13336 {
13337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
13338 }
Katya Nigame7b69a82015-04-28 15:24:06 +053013339 else if (VOS_MONITOR_MODE == hdd_get_conparam())
13340 {
13341 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
13342 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
13343 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13344 hdd_wlan_exit(pHddCtx);
13345 vos_preClose( &pVosContext );
13346 goto done;
13347 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 else
13349 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053013350 /* We wait for active entry threads to exit from driver
13351 * by waiting until rtnl_lock is available.
13352 */
13353 rtnl_lock();
13354 rtnl_unlock();
13355
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053013356 INIT_COMPLETION(pHddCtx->ssr_comp_var);
13357 if ((pHddCtx->isLogpInProgress) && (FALSE ==
13358 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
13359 {
Siddharth Bhala204f572015-01-17 02:03:36 +053013360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053013361 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053013362 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
13363 msecs_to_jiffies(30000));
13364 if(!rc)
13365 {
13366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13367 "%s:SSR timedout, fatal error", __func__);
13368 VOS_BUG(0);
13369 }
13370 }
13371
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053013372 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
13373 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013374
c_hpothu8adb97b2014-12-08 19:38:20 +053013375 /* Driver Need to send country code 00 in below condition
13376 * 1) If gCountryCodePriority is set to 1; and last country
13377 * code set is through 11d. This needs to be done in case
13378 * when NV country code is 00.
13379 * This Needs to be done as when kernel store last country
13380 * code and if stored country code is not through 11d,
13381 * in sme_HandleChangeCountryCodeByUser we will disable 11d
13382 * in next load/unload as soon as we get any country through
13383 * 11d. In sme_HandleChangeCountryCodeByUser
13384 * pMsg->countryCode will be last countryCode and
13385 * pMac->scan.countryCode11d will be country through 11d so
13386 * due to mismatch driver will disable 11d.
13387 *
13388 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053013389
c_hpothu8adb97b2014-12-08 19:38:20 +053013390 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053013391 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053013392 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053013393 {
13394 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053013395 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053013396 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
13397 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053013398
c_hpothu8adb97b2014-12-08 19:38:20 +053013399 //Do all the cleanup before deregistering the driver
13400 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 }
13402
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 vos_preClose( &pVosContext );
13404
13405#ifdef TIMER_MANAGER
13406 vos_timer_exit();
13407#endif
13408#ifdef MEMORY_DEBUG
13409 vos_mem_exit();
13410#endif
13411
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013412#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13413 wlan_logging_sock_deinit_svc();
13414#endif
13415
Jeff Johnson295189b2012-06-20 16:38:30 -070013416done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013417 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013418
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
13420}
13421
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013422/**---------------------------------------------------------------------------
13423
13424 \brief hdd_module_exit() - Exit function
13425
13426 This is the driver exit point (invoked when module is unloaded using rmmod)
13427
13428 \param - None
13429
13430 \return - None
13431
13432 --------------------------------------------------------------------------*/
13433static void __exit hdd_module_exit(void)
13434{
13435 hdd_driver_exit();
13436}
13437
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013438#ifdef MODULE
13439static int fwpath_changed_handler(const char *kmessage,
13440 struct kernel_param *kp)
13441{
Jeff Johnson76052702013-04-16 13:55:05 -070013442 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013443}
13444
13445static int con_mode_handler(const char *kmessage,
13446 struct kernel_param *kp)
13447{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070013448 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013449}
13450#else /* #ifdef MODULE */
13451/**---------------------------------------------------------------------------
13452
Jeff Johnson76052702013-04-16 13:55:05 -070013453 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013454
Jeff Johnson76052702013-04-16 13:55:05 -070013455 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013456 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070013457 - invoked when module parameter fwpath is modified from userspace to signal
13458 initializing the WLAN driver or when con_mode is modified from userspace
13459 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013460
13461 \return - 0 for success, non zero for failure
13462
13463 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070013464static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013465{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013466 int ret_status;
13467
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013468 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013469 ret_status = hdd_driver_init();
13470 wlan_hdd_inited = ret_status ? 0 : 1;
13471 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013472 }
13473
13474 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070013475
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013476 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070013477
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013478 ret_status = hdd_driver_init();
13479 wlan_hdd_inited = ret_status ? 0 : 1;
13480 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013481}
13482
Jeff Johnson295189b2012-06-20 16:38:30 -070013483/**---------------------------------------------------------------------------
13484
Jeff Johnson76052702013-04-16 13:55:05 -070013485 \brief fwpath_changed_handler() - Handler Function
13486
13487 Handle changes to the fwpath parameter
13488
13489 \return - 0 for success, non zero for failure
13490
13491 --------------------------------------------------------------------------*/
13492static int fwpath_changed_handler(const char *kmessage,
13493 struct kernel_param *kp)
13494{
13495 int ret;
13496
13497 ret = param_set_copystring(kmessage, kp);
13498 if (0 == ret)
13499 ret = kickstart_driver();
13500 return ret;
13501}
13502
13503/**---------------------------------------------------------------------------
13504
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013505 \brief con_mode_handler() -
13506
13507 Handler function for module param con_mode when it is changed by userspace
13508 Dynamically linked - do nothing
13509 Statically linked - exit and init driver, as in rmmod and insmod
13510
Jeff Johnson76052702013-04-16 13:55:05 -070013511 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013512
Jeff Johnson76052702013-04-16 13:55:05 -070013513 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013514
13515 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070013516static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013517{
Jeff Johnson76052702013-04-16 13:55:05 -070013518 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013519
Jeff Johnson76052702013-04-16 13:55:05 -070013520 ret = param_set_int(kmessage, kp);
13521 if (0 == ret)
13522 ret = kickstart_driver();
13523 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013524}
13525#endif /* #ifdef MODULE */
13526
13527/**---------------------------------------------------------------------------
13528
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 \brief hdd_get_conparam() -
13530
13531 This is the driver exit point (invoked when module is unloaded using rmmod)
13532
13533 \param - None
13534
13535 \return - tVOS_CON_MODE
13536
13537 --------------------------------------------------------------------------*/
13538tVOS_CON_MODE hdd_get_conparam ( void )
13539{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013540#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013542#else
13543 return (tVOS_CON_MODE)curr_con_mode;
13544#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013545}
13546void hdd_set_conparam ( v_UINT_t newParam )
13547{
13548 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013549#ifndef MODULE
13550 curr_con_mode = con_mode;
13551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013552}
13553/**---------------------------------------------------------------------------
13554
13555 \brief hdd_softap_sta_deauth() - function
13556
13557 This to take counter measure to handle deauth req from HDD
13558
13559 \param - pAdapter - Pointer to the HDD
13560
13561 \param - enable - boolean value
13562
13563 \return - None
13564
13565 --------------------------------------------------------------------------*/
13566
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013567VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
13568 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013569{
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013571 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070013572
13573 ENTER();
13574
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013575 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013576 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013577
13578 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013579 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013580 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070013581
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013582 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070013583
13584 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013585 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070013586}
13587
13588/**---------------------------------------------------------------------------
13589
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013590 \brief hdd_del_all_sta() - function
13591
13592 This function removes all the stations associated on stopping AP/P2P GO.
13593
13594 \param - pAdapter - Pointer to the HDD
13595
13596 \return - None
13597
13598 --------------------------------------------------------------------------*/
13599
13600int hdd_del_all_sta(hdd_adapter_t *pAdapter)
13601{
13602 v_U16_t i;
13603 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013604 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13605 ptSapContext pSapCtx = NULL;
13606 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13607 if(pSapCtx == NULL){
13608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13609 FL("psapCtx is NULL"));
13610 return 1;
13611 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013612 ENTER();
13613
13614 hddLog(VOS_TRACE_LEVEL_INFO,
13615 "%s: Delete all STAs associated.",__func__);
13616 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13617 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
13618 )
13619 {
13620 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13621 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013622 if ((pSapCtx->aStaInfo[i].isUsed) &&
13623 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013624 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013625 struct tagCsrDelStaParams delStaParams;
13626
13627 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013628 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013629 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
13630 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013631 &delStaParams);
13632 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013633 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013634 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013635 }
13636 }
13637 }
13638
13639 EXIT();
13640 return 0;
13641}
13642
13643/**---------------------------------------------------------------------------
13644
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 \brief hdd_softap_sta_disassoc() - function
13646
13647 This to take counter measure to handle deauth req from HDD
13648
13649 \param - pAdapter - Pointer to the HDD
13650
13651 \param - enable - boolean value
13652
13653 \return - None
13654
13655 --------------------------------------------------------------------------*/
13656
13657void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
13658{
13659 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13660
13661 ENTER();
13662
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013663 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013664
13665 //Ignore request to disassoc bcmc station
13666 if( pDestMacAddress[0] & 0x1 )
13667 return;
13668
13669 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
13670}
13671
13672void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
13673{
13674 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13675
13676 ENTER();
13677
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070013678 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013679
13680 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
13681}
13682
Jeff Johnson295189b2012-06-20 16:38:30 -070013683/**---------------------------------------------------------------------------
13684 *
13685 * \brief hdd_get__concurrency_mode() -
13686 *
13687 *
13688 * \param - None
13689 *
13690 * \return - CONCURRENCY MODE
13691 *
13692 * --------------------------------------------------------------------------*/
13693tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
13694{
13695 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13696 hdd_context_t *pHddCtx;
13697
13698 if (NULL != pVosContext)
13699 {
13700 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13701 if (NULL != pHddCtx)
13702 {
13703 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13704 }
13705 }
13706
13707 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013708 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 return VOS_STA;
13710}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013711v_BOOL_t
13712wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13713{
13714 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013715
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013716 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13717 if (pAdapter == NULL)
13718 {
13719 hddLog(VOS_TRACE_LEVEL_INFO,
13720 FL("GO doesn't exist"));
13721 return TRUE;
13722 }
13723 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13724 {
13725 hddLog(VOS_TRACE_LEVEL_INFO,
13726 FL("GO started"));
13727 return TRUE;
13728 }
13729 else
13730 /* wait till GO changes its interface to p2p device */
13731 hddLog(VOS_TRACE_LEVEL_INFO,
13732 FL("Del_bss called, avoid apps suspend"));
13733 return FALSE;
13734
13735}
Jeff Johnson295189b2012-06-20 16:38:30 -070013736/* Decide whether to allow/not the apps power collapse.
13737 * Allow apps power collapse if we are in connected state.
13738 * if not, allow only if we are in IMPS */
13739v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13740{
13741 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013742 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013743 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13745 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13746 hdd_adapter_t *pAdapter = NULL;
13747 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013748 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013749
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13751 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013752
Yathish9f22e662012-12-10 14:21:35 -080013753 concurrent_state = hdd_get_concurrency_mode();
13754
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013755 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13756 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13757 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013758#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013759
Yathish9f22e662012-12-10 14:21:35 -080013760 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013761 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013762 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13763 return TRUE;
13764#endif
13765
Jeff Johnson295189b2012-06-20 16:38:30 -070013766 /*loop through all adapters. TBD fix for Concurrency */
13767 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13768 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13769 {
13770 pAdapter = pAdapterNode->pAdapter;
13771 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13772 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13773 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013774 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013775 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013776 && pmcState != STOPPED && pmcState != STANDBY &&
13777 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013778 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13779 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013781 if(pmcState == FULL_POWER &&
13782 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13783 {
13784 /*
13785 * When SCO indication comes from Coex module , host will
13786 * enter in to full power mode, but this should not prevent
13787 * apps processor power collapse.
13788 */
13789 hddLog(LOG1,
13790 FL("Allow apps power collapse"
13791 "even when sco indication is set"));
13792 return TRUE;
13793 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013794 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053013795 "pmcState = %d scanRspPending = %d "
13796 "inMiddleOfRoaming = %d connected = %d",
13797 __func__, pmcState, scanRspPending,
13798 inMiddleOfRoaming, hdd_connIsConnected(
13799 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
13800 wlan_hdd_get_tdls_stats(pAdapter);
13801 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 }
13803 }
13804 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13805 pAdapterNode = pNext;
13806 }
13807 return TRUE;
13808}
13809
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013810/* Decides whether to send suspend notification to Riva
13811 * if any adapter is in BMPS; then it is required */
13812v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13813{
13814 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13815 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13816
13817 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13818 {
13819 return TRUE;
13820 }
13821 return FALSE;
13822}
13823
Jeff Johnson295189b2012-06-20 16:38:30 -070013824void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13825{
13826 switch(mode)
13827 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013828 case VOS_STA_MODE:
13829 case VOS_P2P_CLIENT_MODE:
13830 case VOS_P2P_GO_MODE:
13831 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013832 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013833 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 break;
13835 default:
13836 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013838 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13839 "Number of open sessions for mode %d = %d"),
13840 pHddCtx->concurrency_mode, mode,
13841 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013842}
13843
13844
13845void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13846{
13847 switch(mode)
13848 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013849 case VOS_STA_MODE:
13850 case VOS_P2P_CLIENT_MODE:
13851 case VOS_P2P_GO_MODE:
13852 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013853 pHddCtx->no_of_open_sessions[mode]--;
13854 if (!(pHddCtx->no_of_open_sessions[mode]))
13855 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013856 break;
13857 default:
13858 break;
13859 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013860 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13861 "Number of open sessions for mode %d = %d"),
13862 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13863
13864}
13865/**---------------------------------------------------------------------------
13866 *
13867 * \brief wlan_hdd_incr_active_session()
13868 *
13869 * This function increments the number of active sessions
13870 * maintained per device mode
13871 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13872 * Incase of SAP/P2P GO upon bss start it is incremented
13873 *
13874 * \param pHddCtx - HDD Context
13875 * \param mode - device mode
13876 *
13877 * \return - None
13878 *
13879 * --------------------------------------------------------------------------*/
13880void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13881{
13882 switch (mode) {
13883 case VOS_STA_MODE:
13884 case VOS_P2P_CLIENT_MODE:
13885 case VOS_P2P_GO_MODE:
13886 case VOS_STA_SAP_MODE:
13887 pHddCtx->no_of_active_sessions[mode]++;
13888 break;
13889 default:
13890 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13891 break;
13892 }
13893 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13894 mode,
13895 pHddCtx->no_of_active_sessions[mode]);
13896}
13897
13898/**---------------------------------------------------------------------------
13899 *
13900 * \brief wlan_hdd_decr_active_session()
13901 *
13902 * This function decrements the number of active sessions
13903 * maintained per device mode
13904 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13905 * Incase of SAP/P2P GO upon bss stop it is decremented
13906 *
13907 * \param pHddCtx - HDD Context
13908 * \param mode - device mode
13909 *
13910 * \return - None
13911 *
13912 * --------------------------------------------------------------------------*/
13913void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13914{
Bhargav Shahd0715912015-10-01 18:17:37 +053013915
Agarwal Ashish51325b52014-06-16 16:50:49 +053013916 switch (mode) {
13917 case VOS_STA_MODE:
13918 case VOS_P2P_CLIENT_MODE:
13919 case VOS_P2P_GO_MODE:
13920 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013921 if (pHddCtx->no_of_active_sessions[mode] > 0)
13922 pHddCtx->no_of_active_sessions[mode]--;
13923 else
13924 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13925 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013926 break;
13927 default:
13928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13929 break;
13930 }
13931 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13932 mode,
13933 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013934}
13935
Jeff Johnsone7245742012-09-05 17:12:55 -070013936/**---------------------------------------------------------------------------
13937 *
13938 * \brief wlan_hdd_restart_init
13939 *
13940 * This function initalizes restart timer/flag. An internal function.
13941 *
13942 * \param - pHddCtx
13943 *
13944 * \return - None
13945 *
13946 * --------------------------------------------------------------------------*/
13947
13948static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13949{
13950 /* Initialize */
13951 pHddCtx->hdd_restart_retries = 0;
13952 atomic_set(&pHddCtx->isRestartInProgress, 0);
13953 vos_timer_init(&pHddCtx->hdd_restart_timer,
13954 VOS_TIMER_TYPE_SW,
13955 wlan_hdd_restart_timer_cb,
13956 pHddCtx);
13957}
13958/**---------------------------------------------------------------------------
13959 *
13960 * \brief wlan_hdd_restart_deinit
13961 *
13962 * This function cleans up the resources used. An internal function.
13963 *
13964 * \param - pHddCtx
13965 *
13966 * \return - None
13967 *
13968 * --------------------------------------------------------------------------*/
13969
13970static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13971{
13972
13973 VOS_STATUS vos_status;
13974 /* Block any further calls */
13975 atomic_set(&pHddCtx->isRestartInProgress, 1);
13976 /* Cleanup */
13977 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13978 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013979 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013980 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13981 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013982 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013983
13984}
13985
13986/**---------------------------------------------------------------------------
13987 *
13988 * \brief wlan_hdd_framework_restart
13989 *
13990 * This function uses a cfg80211 API to start a framework initiated WLAN
13991 * driver module unload/load.
13992 *
13993 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13994 *
13995 *
13996 * \param - pHddCtx
13997 *
13998 * \return - VOS_STATUS_SUCCESS: Success
13999 * VOS_STATUS_E_EMPTY: Adapter is Empty
14000 * VOS_STATUS_E_NOMEM: No memory
14001
14002 * --------------------------------------------------------------------------*/
14003
14004static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
14005{
14006 VOS_STATUS status = VOS_STATUS_SUCCESS;
14007 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014008 int len = (sizeof (struct ieee80211_mgmt));
14009 struct ieee80211_mgmt *mgmt = NULL;
14010
14011 /* Prepare the DEAUTH managment frame with reason code */
14012 mgmt = kzalloc(len, GFP_KERNEL);
14013 if(mgmt == NULL)
14014 {
14015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14016 "%s: memory allocation failed (%d bytes)", __func__, len);
14017 return VOS_STATUS_E_NOMEM;
14018 }
14019 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070014020
14021 /* Iterate over all adapters/devices */
14022 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014023 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
14024 {
14025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014026 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014027 goto end;
14028 }
14029
Jeff Johnsone7245742012-09-05 17:12:55 -070014030 do
14031 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014032 if(pAdapterNode->pAdapter &&
14033 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070014034 {
14035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14036 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
14037 pAdapterNode->pAdapter->dev->name,
14038 pAdapterNode->pAdapter->device_mode,
14039 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014040 /*
14041 * CFG80211 event to restart the driver
14042 *
14043 * 'cfg80211_send_unprot_deauth' sends a
14044 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
14045 * of SME(Linux Kernel) state machine.
14046 *
14047 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
14048 * the driver.
14049 *
14050 */
Abhishek Singh00b71972016-01-07 10:51:04 +053014051
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053014052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
14053 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
14054#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014055 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053014056#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014057 }
14058 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14059 pAdapterNode = pNext;
14060 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
14061
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014062 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014063 /* Free the allocated management frame */
14064 kfree(mgmt);
14065
Jeff Johnsone7245742012-09-05 17:12:55 -070014066 /* Retry until we unload or reach max count */
14067 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
14068 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
14069
14070 return status;
14071
14072}
14073/**---------------------------------------------------------------------------
14074 *
14075 * \brief wlan_hdd_restart_timer_cb
14076 *
14077 * Restart timer callback. An internal function.
14078 *
14079 * \param - User data:
14080 *
14081 * \return - None
14082 *
14083 * --------------------------------------------------------------------------*/
14084
14085void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
14086{
14087 hdd_context_t *pHddCtx = usrDataForCallback;
14088 wlan_hdd_framework_restart(pHddCtx);
14089 return;
14090
14091}
14092
14093
14094/**---------------------------------------------------------------------------
14095 *
14096 * \brief wlan_hdd_restart_driver
14097 *
14098 * This function sends an event to supplicant to restart the WLAN driver.
14099 *
14100 * This function is called from vos_wlanRestart.
14101 *
14102 * \param - pHddCtx
14103 *
14104 * \return - VOS_STATUS_SUCCESS: Success
14105 * VOS_STATUS_E_EMPTY: Adapter is Empty
14106 * VOS_STATUS_E_ALREADY: Request already in progress
14107
14108 * --------------------------------------------------------------------------*/
14109VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
14110{
14111 VOS_STATUS status = VOS_STATUS_SUCCESS;
14112
14113 /* A tight check to make sure reentrancy */
14114 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
14115 {
Mihir Shetefd528652014-06-23 19:07:50 +053014116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070014117 "%s: WLAN restart is already in progress", __func__);
14118
14119 return VOS_STATUS_E_ALREADY;
14120 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070014121 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080014122#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053014123 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070014124#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070014125
Jeff Johnsone7245742012-09-05 17:12:55 -070014126 return status;
14127}
14128
Bhargav Shahd0715912015-10-01 18:17:37 +053014129/**
14130 * hdd_get_total_sessions() - provide total number of active sessions
14131 * @pHddCtx: Valid Global HDD context pointer
14132 *
14133 * This function iterates through pAdaptors and find the number of all active
14134 * sessions. This active sessions includes connected sta, p2p client and number
14135 * of client connected to sap/p2p go.
14136 *
14137 * Return: Total number of active sessions.
14138 */
14139v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
14140{
14141 v_U8_t active_session = 0;
14142 hdd_station_ctx_t *pHddStaCtx;
14143 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14144 hdd_adapter_t *pAdapter;
14145 VOS_STATUS status;
14146
14147 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14148 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
14149 pAdapter = pAdapterNode->pAdapter;
14150 switch (pAdapter->device_mode) {
14151 case VOS_STA_MODE:
14152 case VOS_P2P_CLIENT_MODE:
14153 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14154 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14155 active_session += 1;
14156 break;
14157 case VOS_STA_SAP_MODE:
14158 case VOS_P2P_GO_MODE:
14159 active_session += hdd_softap_get_connected_sta(pAdapter);
14160 break;
14161 default:
14162 break;
14163 }
14164
14165 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
14166 pAdapterNode = pNext;
14167 }
14168
14169 return active_session;
14170}
14171
14172/**
14173 * hdd_set_delack_value() - Set delack value
14174 * @pHddCtx: Valid Global HDD context pointer
14175 * @next_rx_level: Value to set for delack
14176 *
14177 * This function compare present value and next value of delack. If the both
14178 * are diffrent then it sets next value .
14179 *
14180 * Return: void.
14181 */
14182void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
14183{
14184 if (pHddCtx->cur_rx_level != next_rx_level) {
14185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
14186 "%s: TCP DELACK trigger level %d",
14187 __func__, next_rx_level);
14188 mutex_lock(&pHddCtx->cur_rx_level_lock);
14189 pHddCtx->cur_rx_level = next_rx_level;
14190 mutex_unlock(&pHddCtx->cur_rx_level_lock);
14191 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
14192 sizeof(next_rx_level));
14193 }
14194}
14195
14196/**
14197 * hdd_set_default_stop_delack_timer() - Start delack timer
14198 * @pHddCtx: Valid Global HDD context pointer
14199 *
14200 * This function stop delack timer and set delack value to default..
14201 *
14202 * Return: void.
14203 */
14204
14205void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
14206{
14207 if (VOS_TIMER_STATE_RUNNING !=
14208 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
14209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
14210 "%s: Can not stop timer", __func__);
14211 return;
14212 }
14213
14214 vos_timer_stop(&pHddCtx->delack_timer);
14215 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
14216}
14217
14218/**
14219 * hdd_start_delack_timer() - Start delack timer
14220 * @pHddCtx: Valid Global HDD context pointer
14221 *
14222 * This function starts the delack timer for tcpDelAckComputeInterval time
14223 * interval.The default timer value is 2 second.
14224 *
14225 * Return: void.
14226 */
14227void hdd_start_delack_timer(hdd_context_t *pHddCtx)
14228{
14229 if (VOS_TIMER_STATE_RUNNING ==
14230 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
14231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
14232 "%s: Timer is already running", __func__);
14233 return;
14234 }
14235
14236 vos_timer_start(&pHddCtx->delack_timer,
14237 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
14238}
14239
14240/**
14241 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
14242 * @pHddCtx: Valid Global HDD context pointer
14243 *
14244 * This function updates the prev_rx_packets count from the corresponding
14245 * pAdapter states. This prev_rx_packets will diffed with the packet count
14246 * at the end of delack timer. That can give number of RX packet is spacific
14247 * time.
14248 *
14249 * Return: void.
14250 */
14251void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
14252{
14253 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14254 hdd_adapter_t *pAdapter;
14255 VOS_STATUS status;
14256
14257 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14258 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
14259 pAdapter = pAdapterNode->pAdapter;
14260 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
14261 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14262 pAdapterNode = pNext;
14263 }
14264}
14265
14266/**
14267 * hdd_manage_delack_timer() - start\stop delack timer
14268 * @pHddCtx: Valid Global HDD context pointer
14269 *
14270 * This function check the number of concerent session present, it starts the
14271 * delack timer if only one session is present.
14272 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
14273 *
14274 * Return: void.
14275 */
14276void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
14277{
14278 uint8_t sessions;
14279
14280 if (!pHddCtx->cfg_ini->enable_delack) {
14281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
14282 "%s: TCP DELACK is not enabled", __func__);
14283 return;
14284 }
14285
14286 /* Blindly stop timer of BTCOEX and TDLS Session is up */
14287 if (pHddCtx->mode != 0) {
14288 hdd_set_default_stop_delack_timer(pHddCtx);
14289 return;
14290 }
14291
14292 sessions = hdd_get_total_sessions(pHddCtx);
14293 if (sessions == 1) {
14294 hdd_update_prev_rx_packet_count(pHddCtx);
14295 hdd_start_delack_timer(pHddCtx);
14296 } else {
14297 hdd_set_default_stop_delack_timer(pHddCtx);
14298 }
14299}
14300
Mihir Shetee1093ba2014-01-21 20:13:32 +053014301/**---------------------------------------------------------------------------
14302 *
14303 * \brief wlan_hdd_init_channels
14304 *
14305 * This function is used to initialize the channel list in CSR
14306 *
14307 * This function is called from hdd_wlan_startup
14308 *
14309 * \param - pHddCtx: HDD context
14310 *
14311 * \return - VOS_STATUS_SUCCESS: Success
14312 * VOS_STATUS_E_FAULT: Failure reported by SME
14313
14314 * --------------------------------------------------------------------------*/
14315static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
14316{
14317 eHalStatus status;
14318
14319 status = sme_InitChannels(pHddCtx->hHal);
14320 if (HAL_STATUS_SUCCESS(status))
14321 {
14322 return VOS_STATUS_SUCCESS;
14323 }
14324 else
14325 {
14326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
14327 __func__, status);
14328 return VOS_STATUS_E_FAULT;
14329 }
14330}
14331
Mihir Shete04206452014-11-20 17:50:58 +053014332#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053014333VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014334{
14335 eHalStatus status;
14336
Agarwal Ashish6db9d532014-09-30 18:19:10 +053014337 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014338 if (HAL_STATUS_SUCCESS(status))
14339 {
14340 return VOS_STATUS_SUCCESS;
14341 }
14342 else
14343 {
14344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
14345 __func__, status);
14346 return VOS_STATUS_E_FAULT;
14347 }
14348}
Mihir Shete04206452014-11-20 17:50:58 +053014349#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070014350/*
14351 * API to find if there is any STA or P2P-Client is connected
14352 */
14353VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
14354{
14355 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
14356}
Jeff Johnsone7245742012-09-05 17:12:55 -070014357
Mihir Shetee2ae82a2015-03-16 14:08:49 +053014358
14359/*
14360 * API to find if the firmware will send logs using DXE channel
14361 */
14362v_U8_t hdd_is_fw_logging_enabled(void)
14363{
14364 hdd_context_t *pHddCtx;
14365
14366 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
14367 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
14368
Sachin Ahuja084313e2015-05-21 17:57:10 +053014369 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053014370}
14371
Agarwal Ashish57e84372014-12-05 18:26:53 +053014372/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053014373 * API to find if the firmware will send trace logs using DXE channel
14374 */
14375v_U8_t hdd_is_fw_ev_logging_enabled(void)
14376{
14377 hdd_context_t *pHddCtx;
14378
14379 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
14380 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
14381
14382 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
14383}
14384/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053014385 * API to find if there is any session connected
14386 */
14387VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
14388{
14389 return sme_is_any_session_connected(pHddCtx->hHal);
14390}
14391
14392
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014393int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
14394{
14395 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14396 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053014397 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053014398 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014399
14400 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053014401 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014402 if (pScanInfo->mScanPending)
14403 {
c_hpothua3d45d52015-01-05 14:11:17 +053014404 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
14405 eCSR_SCAN_ABORT_DEFAULT);
14406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14407 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014408
c_hpothua3d45d52015-01-05 14:11:17 +053014409 /* If there is active scan command lets wait for the completion else
14410 * there is no need to wait as scan command might be in the SME pending
14411 * command list.
14412 */
14413 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
14414 {
Mukul Sharmab392b642017-08-17 17:45:29 +053014415 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014416 &pScanInfo->abortscan_event_var,
14417 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053014418 if (0 >= status)
14419 {
14420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053014421 "%s: Timeout or Interrupt occurred while waiting for abort"
14422 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053014423 return -ETIMEDOUT;
14424 }
14425 }
14426 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
14427 {
14428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14429 FL("hdd_abort_mac_scan failed"));
14430 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014431 }
14432 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053014433 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014434}
14435
Abhishek Singh7d624e12015-11-30 14:29:27 +053014436/**
14437 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
14438 * user space
14439 * @frame_ind: Management frame data to be informed.
14440 *
14441 * This function is used to indicate management frame to
14442 * user space
14443 *
14444 * Return: None
14445 *
14446 */
14447void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
14448{
14449 hdd_context_t *hdd_ctx = NULL;
14450 hdd_adapter_t *adapter = NULL;
14451 v_CONTEXT_t vos_context = NULL;
14452
14453 /* Get the global VOSS context.*/
14454 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14455 if (!vos_context) {
14456 hddLog(LOGE, FL("Global VOS context is Null"));
14457 return;
14458 }
14459 /* Get the HDD context.*/
14460 hdd_ctx =
14461 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
14462
14463 if (0 != wlan_hdd_validate_context(hdd_ctx))
14464 {
14465 return;
14466 }
14467 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
14468 frame_ind->sessionId);
14469
14470 if ((NULL != adapter) &&
14471 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
14472 __hdd_indicate_mgmt_frame(adapter,
14473 frame_ind->frameLen,
14474 frame_ind->frameBuf,
14475 frame_ind->frameType,
14476 frame_ind->rxChan,
14477 frame_ind->rxRssi);
14478 return;
14479
14480}
14481
c_hpothu225aa7c2014-10-22 17:45:13 +053014482VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
14483{
14484 hdd_adapter_t *pAdapter;
14485 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14486 VOS_STATUS vosStatus;
14487
14488 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14489 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
14490 {
14491 pAdapter = pAdapterNode->pAdapter;
14492 if (NULL != pAdapter)
14493 {
14494 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
14495 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
14496 WLAN_HDD_P2P_GO == pAdapter->device_mode)
14497 {
14498 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
14499 pAdapter->device_mode);
14500 if (VOS_STATUS_SUCCESS !=
14501 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
14502 {
14503 hddLog(LOGE, FL("failed to abort ROC"));
14504 return VOS_STATUS_E_FAILURE;
14505 }
14506 }
14507 }
14508 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14509 pAdapterNode = pNext;
14510 }
14511 return VOS_STATUS_SUCCESS;
14512}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053014513
Mihir Shete0be28772015-02-17 18:42:14 +053014514hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
14515{
14516 hdd_adapter_t *pAdapter;
14517 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14518 hdd_cfg80211_state_t *cfgState;
14519 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
14520 VOS_STATUS vosStatus;
14521
14522 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
14523 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
14524 {
14525 pAdapter = pAdapterNode->pAdapter;
14526 if (NULL != pAdapter)
14527 {
14528 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
14529 pRemainChanCtx = cfgState->remain_on_chan_ctx;
14530 if (pRemainChanCtx)
14531 break;
14532 }
14533 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
14534 pAdapterNode = pNext;
14535 }
14536 return pRemainChanCtx;
14537}
14538
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053014539/**
14540 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
14541 *
14542 * @pHddCtx: HDD context within host driver
14543 * @dfsScanMode: dfsScanMode passed from ioctl
14544 *
14545 */
14546
14547VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
14548 tANI_U8 dfsScanMode)
14549{
14550 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14551 hdd_adapter_t *pAdapter;
14552 VOS_STATUS vosStatus;
14553 hdd_station_ctx_t *pHddStaCtx;
14554 eHalStatus status = eHAL_STATUS_SUCCESS;
14555
14556 if(!pHddCtx)
14557 {
14558 hddLog(LOGE, FL("HDD context is Null"));
14559 return eHAL_STATUS_FAILURE;
14560 }
14561
14562 if (pHddCtx->scan_info.mScanPending)
14563 {
14564 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
14565 pHddCtx->scan_info.sessionId);
14566 hdd_abort_mac_scan(pHddCtx,
14567 pHddCtx->scan_info.sessionId,
14568 eCSR_SCAN_ABORT_DEFAULT);
14569 }
14570
14571 if (!dfsScanMode)
14572 {
14573 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
14574 while ((NULL != pAdapterNode) &&
14575 (VOS_STATUS_SUCCESS == vosStatus))
14576 {
14577 pAdapter = pAdapterNode->pAdapter;
14578
14579 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
14580 {
14581 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14582
14583 if(!pHddStaCtx)
14584 {
14585 hddLog(LOGE, FL("HDD STA context is Null"));
14586 return eHAL_STATUS_FAILURE;
14587 }
14588
14589 /* if STA is already connected on DFS channel,
14590 disconnect immediately*/
14591 if (hdd_connIsConnected(pHddStaCtx) &&
14592 (NV_CHANNEL_DFS ==
14593 vos_nv_getChannelEnabledState(
14594 pHddStaCtx->conn_info.operationChannel)))
14595 {
14596 status = sme_RoamDisconnect(pHddCtx->hHal,
14597 pAdapter->sessionId,
14598 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14599 hddLog(LOG1, FL("Client connected on DFS channel %d,"
14600 "sme_RoamDisconnect returned with status: %d"
14601 "for sessionid: %d"), pHddStaCtx->conn_info.
14602 operationChannel, status, pAdapter->sessionId);
14603 }
14604 }
14605
14606 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
14607 &pNext);
14608 pAdapterNode = pNext;
14609 }
14610 }
14611
14612 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
14613 sme_UpdateDFSRoamMode(pHddCtx->hHal,
14614 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
14615
14616 status = sme_HandleDFSChanScan(pHddCtx->hHal);
14617 if (!HAL_STATUS_SUCCESS(status))
14618 {
14619 hddLog(LOGE,
14620 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
14621 return status;
14622 }
14623
14624 return status;
14625}
14626
Nirav Shah7e3c8132015-06-22 23:51:42 +053014627static int hdd_log2_ceil(unsigned value)
14628{
14629 /* need to switch to unsigned math so that negative values
14630 * will right-shift towards 0 instead of -1
14631 */
14632 unsigned tmp = value;
14633 int log2 = -1;
14634
14635 if (value == 0)
14636 return 0;
14637
14638 while (tmp) {
14639 log2++;
14640 tmp >>= 1;
14641 }
14642 if (1U << log2 != value)
14643 log2++;
14644
14645 return log2;
14646}
14647
14648/**
14649 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
14650 * @pAdapter: adapter handle
14651 *
14652 * Return: vos status
14653 */
14654VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
14655{
14656 int hash_elem, log2, i;
14657
14658 spin_lock_bh( &pAdapter->sta_hash_lock);
14659 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
14660 spin_unlock_bh( &pAdapter->sta_hash_lock);
14661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14662 "%s: hash already attached for session id %d",
14663 __func__, pAdapter->sessionId);
14664 return VOS_STATUS_SUCCESS;
14665 }
14666 spin_unlock_bh( &pAdapter->sta_hash_lock);
14667
14668 hash_elem = WLAN_MAX_STA_COUNT;
14669 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
14670 log2 = hdd_log2_ceil(hash_elem);
14671 hash_elem = 1 << log2;
14672
14673 pAdapter->sta_id_hash.mask = hash_elem - 1;
14674 pAdapter->sta_id_hash.idx_bits = log2;
14675 pAdapter->sta_id_hash.bins =
14676 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
14677 if (!pAdapter->sta_id_hash.bins) {
14678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14679 "%s: malloc failed for session %d",
14680 __func__, pAdapter->sessionId);
14681 return VOS_STATUS_E_NOMEM;
14682 }
14683
14684 for (i = 0; i < hash_elem; i++)
14685 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
14686
14687 spin_lock_bh( &pAdapter->sta_hash_lock);
14688 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
14689 spin_unlock_bh( &pAdapter->sta_hash_lock);
14690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14691 "%s: Station ID Hash attached for session id %d",
14692 __func__, pAdapter->sessionId);
14693
14694 return VOS_STATUS_SUCCESS;
14695}
14696
14697/**
14698 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
14699 * @pAdapter: adapter handle
14700 *
14701 * Return: vos status
14702 */
14703VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14704{
14705 int hash_elem, i;
14706 v_SIZE_t size;
14707
14708 spin_lock_bh( &pAdapter->sta_hash_lock);
14709 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14710 spin_unlock_bh( &pAdapter->sta_hash_lock);
14711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14712 "%s: hash not initialized for session id %d",
14713 __func__, pAdapter->sessionId);
14714 return VOS_STATUS_SUCCESS;
14715 }
14716
14717 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14718 spin_unlock_bh( &pAdapter->sta_hash_lock);
14719
14720 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14721
14722 /* free all station info*/
14723 for (i = 0; i < hash_elem; i++) {
14724 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14725 if (size != 0) {
14726 VOS_STATUS status;
14727 hdd_staid_hash_node_t *sta_info_node = NULL;
14728 hdd_staid_hash_node_t *next_node = NULL;
14729 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14730 (hdd_list_node_t**) &sta_info_node );
14731
14732 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14733 {
14734 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14735 &sta_info_node->node);
14736 vos_mem_free(sta_info_node);
14737
14738 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14739 (hdd_list_node_t*)sta_info_node,
14740 (hdd_list_node_t**)&next_node);
14741 sta_info_node = next_node;
14742 }
14743 }
14744 }
14745
14746 vos_mem_free(pAdapter->sta_id_hash.bins);
14747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14748 "%s: Station ID Hash detached for session id %d",
14749 __func__, pAdapter->sessionId);
14750 return VOS_STATUS_SUCCESS;
14751}
14752
14753/**
14754 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14755 * @pAdapter: adapter handle
14756 * @mac_addr_in: input mac address
14757 *
14758 * Return: index derived from mac address
14759 */
14760int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14761 v_MACADDR_t *mac_addr_in)
14762{
14763 uint16 index;
14764 struct hdd_align_mac_addr_t * mac_addr =
14765 (struct hdd_align_mac_addr_t *)mac_addr_in;
14766
14767 index = mac_addr->bytes_ab ^
14768 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14769 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14770 index &= pAdapter->sta_id_hash.mask;
14771 return index;
14772}
14773
14774/**
14775 * hdd_sta_id_hash_add_entry() - add entry in hash
14776 * @pAdapter: adapter handle
14777 * @sta_id: station id
14778 * @mac_addr: mac address
14779 *
14780 * Return: vos status
14781 */
14782VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14783 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14784{
14785 uint16 index;
14786 hdd_staid_hash_node_t *sta_info_node = NULL;
14787
Nirav Shah7e3c8132015-06-22 23:51:42 +053014788 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14789 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14790 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14792 "%s: malloc failed", __func__);
14793 return VOS_STATUS_E_NOMEM;
14794 }
14795
14796 sta_info_node->sta_id = sta_id;
14797 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14798
Nirav Shah303ed5c2015-08-24 10:29:25 +053014799 spin_lock_bh( &pAdapter->sta_hash_lock);
14800 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14801 spin_unlock_bh( &pAdapter->sta_hash_lock);
14802 vos_mem_free(sta_info_node);
14803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14804 "%s: hash is not initialized for session id %d",
14805 __func__, pAdapter->sessionId);
14806 return VOS_STATUS_E_FAILURE;
14807 }
14808
Nirav Shah7e3c8132015-06-22 23:51:42 +053014809 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14810 (hdd_list_node_t*) sta_info_node );
14811 spin_unlock_bh( &pAdapter->sta_hash_lock);
14812 return VOS_STATUS_SUCCESS;
14813}
14814
14815/**
14816 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14817 * @pAdapter: adapter handle
14818 * @sta_id: station id
14819 * @mac_addr: mac address
14820 *
14821 * Return: vos status
14822 */
14823VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14824 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14825{
14826 uint16 index;
14827 VOS_STATUS status;
14828 hdd_staid_hash_node_t *sta_info_node = NULL;
14829 hdd_staid_hash_node_t *next_node = NULL;
14830
14831 spin_lock_bh( &pAdapter->sta_hash_lock);
14832 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14833 spin_unlock_bh( &pAdapter->sta_hash_lock);
14834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14835 "%s: hash is not initialized for session id %d",
14836 __func__, pAdapter->sessionId);
14837 return VOS_STATUS_E_FAILURE;
14838 }
14839
14840 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14841 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14842 (hdd_list_node_t**) &sta_info_node );
14843
14844 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14845 {
14846 if (sta_info_node->sta_id == sta_id) {
14847 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14848 &sta_info_node->node);
14849 vos_mem_free(sta_info_node);
14850 break;
14851 }
14852 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14853 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14854 sta_info_node = next_node;
14855 }
14856 spin_unlock_bh( &pAdapter->sta_hash_lock);
14857 return status;
14858}
14859
14860/**
14861 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14862 * @pAdapter: adapter handle
14863 * @mac_addr_in: mac address
14864 *
14865 * Return: station id
14866 */
14867int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14868 v_MACADDR_t *mac_addr_in)
14869{
14870 uint8 is_found = 0;
14871 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14872 uint16 index;
14873 VOS_STATUS status;
14874 hdd_staid_hash_node_t *sta_info_node = NULL;
14875 hdd_staid_hash_node_t *next_node = NULL;
14876
14877 spin_lock_bh( &pAdapter->sta_hash_lock);
14878 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14879 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014880 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014881 FL("hash is not initialized for session id %d"),
14882 pAdapter->sessionId);
14883 return HDD_WLAN_INVALID_STA_ID;
14884 }
14885
14886 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14887 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14888 (hdd_list_node_t**) &sta_info_node );
14889
14890 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14891 {
14892 if (vos_mem_compare(&sta_info_node->mac_addr,
14893 mac_addr_in, sizeof(v_MACADDR_t))) {
14894 is_found = 1;
14895 sta_id = sta_info_node->sta_id;
14896 break;
14897 }
14898 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14899 (hdd_list_node_t*)sta_info_node,
14900 (hdd_list_node_t**)&next_node);
14901 sta_info_node = next_node;
14902 }
14903 spin_unlock_bh( &pAdapter->sta_hash_lock);
14904 return sta_id;
14905}
14906
c_manjeecfd1efb2015-09-25 19:32:34 +053014907/*FW memory dump feature*/
14908/**
14909 * This structure hold information about the /proc file
14910 *
14911 */
14912static struct proc_dir_entry *proc_file, *proc_dir;
14913
14914/**
14915 * memdump_read() - perform read operation in memory dump proc file
14916 *
14917 * @file - handle for the proc file.
14918 * @buf - pointer to user space buffer.
14919 * @count - number of bytes to be read.
14920 * @pos - offset in the from buffer.
14921 *
14922 * This function performs read operation for the memory dump proc file.
14923 *
14924 * Return: number of bytes read on success, error code otherwise.
14925 */
14926static ssize_t memdump_read(struct file *file, char __user *buf,
14927 size_t count, loff_t *pos)
14928{
14929 int status;
14930 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14931 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014932 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014933 ENTER();
14934
14935 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14936 status = wlan_hdd_validate_context(hdd_ctx);
14937 if (0 != status) {
14938 return -EINVAL;
14939 }
14940
14941 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14942 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14943 return -EINVAL;
14944 }
14945
14946 /* run fs_read_handler in an atomic context*/
14947 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014948 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14949 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014950 {
14951 /*Free the fwr mem dump buffer */
14952 wlan_free_fwr_mem_dump_buffer();
14953 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014954 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014955 }
14956 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14957 vos_ssr_unprotect(__func__);
14958 EXIT();
14959 return ret_count;
14960}
14961
14962/**
14963 * struct memdump_fops - file operations for memory dump feature
14964 * @read - read function for memory dump operation.
14965 *
14966 * This structure initialize the file operation handle for memory
14967 * dump feature
14968 */
14969static const struct file_operations memdump_fops = {
14970 read: memdump_read
14971};
14972
14973/*
14974* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14975* To be passed by HDD to WDA and called upon receiving of response
14976* from firmware
14977* @fwMemDumpReqContext : memory dump request context
14978* @dump_rsp : dump response from HAL
14979* Returns none
14980*/
14981void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14982 tAniFwrDumpRsp *dump_rsp)
14983{
c_manjeef1495642015-10-13 18:35:01 +053014984 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014985
c_manjeef1495642015-10-13 18:35:01 +053014986 ENTER();
14987 spin_lock(&hdd_context_lock);
14988 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14989 spin_unlock(&hdd_context_lock);
14990 return;
14991 }
14992 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014993 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014994 hddLog(LOGE, FL("fw dump request declined by fwr"));
14995 //set the request completion variable
14996 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014997 //Free the allocated fwr dump
14998 wlan_free_fwr_mem_dump_buffer();
14999 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053015000 }
c_manjeef1495642015-10-13 18:35:01 +053015001 else {
15002 hddLog(LOG1, FL("fw dump request accepted by fwr"));
15003 /* register the HDD callback which will be called by SVC */
15004 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
15005 }
15006 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053015007 EXIT();
15008
15009}
15010
15011/**
15012 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
15013 *
15014 * This function removes file/dir under proc file system that was
15015 * processing firmware memory dump
15016 *
15017 * Return: None
15018 */
15019static void memdump_procfs_remove(void)
15020{
15021 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
15022 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
15023 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
15024 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
15025 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
15026}
15027
15028/**
15029 * memdump_procfs_init() - Initialize procfs for memory dump
15030 *
15031 * @vos_ctx - Global vos context.
15032 *
15033 * This function create file under proc file system to be used later for
15034 * processing firmware memory dump
15035 *
15036 * Return: 0 on success, error code otherwise.
15037 */
15038static int memdump_procfs_init(void *vos_ctx)
15039{
15040 hdd_context_t *hdd_ctx;
15041
15042 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15043 if (!hdd_ctx) {
15044 hddLog(LOGE , FL("Invalid HDD context"));
15045 return -EINVAL;
15046 }
15047
15048 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
15049 if (proc_dir == NULL) {
15050 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
15051 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
15052 PROCFS_MEMDUMP_DIR);
15053 return -ENOMEM;
15054 }
15055
15056 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
15057 S_IRUSR | S_IWUSR, proc_dir,
15058 &memdump_fops, hdd_ctx);
15059 if (proc_file == NULL) {
15060 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
15061 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
15062 PROCFS_MEMDUMP_NAME);
15063 return -ENOMEM;
15064 }
15065
15066 hddLog(LOG1 , FL("/proc/%s/%s created"),
15067 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
15068
15069 return 0;
15070}
15071
15072/**
15073 * memdump_init() - Initialization function for memory dump feature
15074 *
15075 * This function creates proc file for memdump feature and registers
15076 * HDD callback function with SME.
15077 *
15078 * Return - 0 on success, error otherwise
15079 */
15080int memdump_init(void)
15081{
15082 hdd_context_t *hdd_ctx;
15083 void *vos_ctx;
15084 int status = 0;
15085
15086 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15087 if (!vos_ctx) {
15088 hddLog(LOGE, FL("Invalid VOS context"));
15089 return -EINVAL;
15090 }
15091
15092 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15093 if (!hdd_ctx) {
15094 hddLog(LOGE , FL("Invalid HDD context"));
15095 return -EINVAL;
15096 }
15097
15098 status = memdump_procfs_init(vos_ctx);
15099 if (status) {
15100 hddLog(LOGE , FL("Failed to create proc file"));
15101 return status;
15102 }
15103
15104 return 0;
15105}
15106
15107/**
15108 * memdump_deinit() - De initialize memdump feature
15109 *
15110 * This function removes proc file created for memdump feature.
15111 *
15112 * Return: None
15113 */
15114int memdump_deinit(void)
15115{
15116 hdd_context_t *hdd_ctx;
15117 void *vos_ctx;
15118
15119 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15120 if (!vos_ctx) {
15121 hddLog(LOGE, FL("Invalid VOS context"));
15122 return -EINVAL;
15123 }
15124
15125 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15126 if(!hdd_ctx) {
15127 hddLog(LOGE , FL("Invalid HDD context"));
15128 return -EINVAL;
15129 }
15130
15131 memdump_procfs_remove();
15132 return 0;
15133}
15134
15135/**
15136 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
15137 * Return: HAL status
15138 */
15139
15140int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
15141{
15142 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053015143 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053015144 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053015145 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053015146 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053015147
c_manjeecfd1efb2015-09-25 19:32:34 +053015148 /*Check whether a dump request is already going on
15149 *Caution this function will free previously held memory if new dump request is allowed*/
15150 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
15151 hddLog(LOGE, FL("Fw memdump already in progress"));
15152 return -EBUSY;
15153 }
15154 //Allocate memory for fw mem dump buffer
15155 ret = wlan_fwr_mem_dump_buffer_allocation();
15156 if(ret == -EFAULT)
15157 {
15158 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
15159 return ret;
15160 }
15161 if (0 != ret) {
15162 hddLog(LOGE, FL("Fwr mem Allocation failed"));
15163 return -ENOMEM;
15164 }
c_manjeef1495642015-10-13 18:35:01 +053015165 init_completion(&fw_mem_dump_ctx.req_completion);
15166 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
15167 fw_mem_dump_ctx.status = false;
15168
c_manjeecfd1efb2015-09-25 19:32:34 +053015169 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053015170 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053015171 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
15172 if(eHAL_STATUS_SUCCESS != status)
15173 {
15174 hddLog(VOS_TRACE_LEVEL_ERROR,
15175 "%s: fw_mem_dump_req failed ", __func__);
15176 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053015177 ret = -EFAULT;
15178 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053015179 }
c_manjeef1495642015-10-13 18:35:01 +053015180 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053015181 result =
15182 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
15183 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
15184 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053015185 {
15186 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053015187 "%s: fw_mem_dump_req timeout %d ", __func__,result);
15188 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053015189 }
15190cleanup:
15191 spin_lock(&hdd_context_lock);
15192 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053015193 if(!ret && !fw_mem_dump_ctx.status)
15194 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053015195 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053015196
c_manjeef1495642015-10-13 18:35:01 +053015197 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053015198 return ret;
c_manjeef1495642015-10-13 18:35:01 +053015199}
15200
15201/**
15202 * HDD callback which will be called by SVC to indicate mem dump completion.
15203 */
15204void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
15205{
15206 if (!pHddFwMemDumpCtx) {
15207 hddLog(VOS_TRACE_LEVEL_ERROR,
15208 "%s: HDD context not valid ", __func__);
15209 return;
15210 }
15211 spin_lock(&hdd_context_lock);
15212 /* check the req magic and set status */
15213 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
15214 {
15215 pHddFwMemDumpCtx->status = true;
15216 //signal the completion
15217 complete(&(pHddFwMemDumpCtx->req_completion));
15218 }
15219 else
15220 {
15221 hddLog(VOS_TRACE_LEVEL_ERROR,
15222 "%s: fw mem dump request possible timeout ", __func__);
15223 }
15224 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053015225}
15226
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053015227void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
15228{
15229 if (NULL == pAdapter)
15230 {
15231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
15232 return;
15233 }
15234 init_completion(&pAdapter->session_open_comp_var);
15235 init_completion(&pAdapter->session_close_comp_var);
15236 init_completion(&pAdapter->disconnect_comp_var);
15237 init_completion(&pAdapter->linkup_event_var);
15238 init_completion(&pAdapter->cancel_rem_on_chan_var);
15239 init_completion(&pAdapter->rem_on_chan_ready_event);
15240 init_completion(&pAdapter->pno_comp_var);
15241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15242 init_completion(&pAdapter->offchannel_tx_event);
15243#endif
15244 init_completion(&pAdapter->tx_action_cnf_event);
15245#ifdef FEATURE_WLAN_TDLS
15246 init_completion(&pAdapter->tdls_add_station_comp);
15247 init_completion(&pAdapter->tdls_del_station_comp);
15248 init_completion(&pAdapter->tdls_mgmt_comp);
15249 init_completion(&pAdapter->tdls_link_establish_req_comp);
15250#endif
15251
15252#ifdef WLAN_FEATURE_RMC
15253 init_completion(&pAdapter->ibss_peer_info_comp);
15254#endif /* WLAN_FEATURE_RMC */
15255 init_completion(&pAdapter->ula_complete);
15256 init_completion(&pAdapter->change_country_code);
15257
15258#ifdef FEATURE_WLAN_BATCH_SCAN
15259 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
15260 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
15261#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053015262 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053015263
15264 return;
15265}
c_manjeecfd1efb2015-09-25 19:32:34 +053015266
Anurag Chouhan0b29de02016-12-16 13:18:40 +053015267#ifdef MDNS_OFFLOAD
15268
15269/**
15270 * hdd_mdns_enable_offload_done() - mdns enable offload response api
15271 * @padapter: holds adapter
15272 * @status: response status
15273 *
15274 * Return - None
15275 */
15276void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
15277{
15278 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
15279
15280 ENTER();
15281
15282 if (NULL == adapter)
15283 {
15284 hddLog(VOS_TRACE_LEVEL_ERROR,
15285 "%s: adapter is NULL",__func__);
15286 return;
15287 }
15288
15289 adapter->mdns_status.mdns_enable_status = status;
15290 vos_event_set(&adapter->mdns_status.vos_event);
15291 return;
15292}
15293
15294/**
15295 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
15296 * @padapter: holds adapter
15297 * @status: responce status
15298 *
15299 * Return - None
15300 */
15301void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
15302{
15303 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
15304
15305 ENTER();
15306
15307 if (NULL == adapter)
15308 {
15309 hddLog(VOS_TRACE_LEVEL_ERROR,
15310 "%s: adapter is NULL",__func__);
15311 return;
15312 }
15313
15314 adapter->mdns_status.mdns_fqdn_status = status;
15315 return;
15316}
15317
15318/**
15319 * hdd_mdns_resp_offload_done() - mdns resp offload response api
15320 * @padapter: holds adapter
15321 * @status: responce status
15322 *
15323 * Return - None
15324 */
15325void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
15326{
15327 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
15328
15329 ENTER();
15330
15331 if (NULL == adapter)
15332 {
15333 hddLog(VOS_TRACE_LEVEL_ERROR,
15334 "%s: adapter is NULL",__func__);
15335 return;
15336 }
15337
15338 adapter->mdns_status.mdns_resp_status = status;
15339 return;
15340}
15341
15342/**
15343 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
15344 * @response: Pointer to a struct hdd_mdns_resp_info
15345 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15346 *
15347 * This function will pack the whole domain name without compression. It will
15348 * add the leading len for each field and add zero length octet to terminate
15349 * the domain name.
15350 *
15351 * Return: Return boolean. TRUE for success, FALSE for fail.
15352 */
15353static bool
15354wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
15355 sir_mdns_resp_info resp_info)
15356{
15357 uint8_t num;
15358 uint16_t idx;
15359 uint8_t len = 0;
15360
15361 if ((response == NULL) || (response->data == NULL) ||
15362 (response->offset == NULL)) {
15363 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
15364 return FALSE;
15365 }
15366
15367 if ((resp_info == NULL) ||
15368 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
15369 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15370 return FALSE;
15371 }
15372
15373 for (num = 0; num < response->num_entries; num++) {
15374 response->offset[num] =
15375 resp_info->resp_len + MDNS_HEADER_LEN;
15376 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15377 len = strlen((char *)&response->data[idx]);
15378 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
15379 hddLog(LOGE, FL("resp_len exceeds %d!"),
15380 MAX_MDNS_RESP_LEN);
15381 return FALSE;
15382 }
15383 resp_info->resp_data[resp_info->resp_len] = len;
15384 resp_info->resp_len++;
15385 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15386 &response->data[idx], len);
15387 resp_info->resp_len += len;
15388 }
15389
15390 /* The domain name terminates with the zero length octet */
15391 if (num == response->num_entries) {
15392 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
15393 hddLog(LOGE, FL("resp_len exceeds %d!"),
15394 MAX_MDNS_RESP_LEN);
15395 return FALSE;
15396 }
15397 resp_info->resp_data[resp_info->resp_len] = 0;
15398 resp_info->resp_len++;
15399 }
15400
15401 return TRUE;
15402}
15403
15404/**
15405 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
15406 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
15407 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15408 *
15409 * Return: None
15410 */
15411static void wlan_hdd_mdns_format_response_u16(uint16_t value,
15412 sir_mdns_resp_info resp_info)
15413{
15414 uint8_t val_u8;
15415
15416 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
15417 return;
15418 val_u8 = (value & 0xff00) >> 8;
15419 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15420 val_u8 = value & 0xff;
15421 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15422}
15423
15424/**
15425 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
15426 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
15427 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15428 *
15429 * Return: None
15430 */
15431static void wlan_hdd_mdns_format_response_u32(uint32_t value,
15432 sir_mdns_resp_info resp_info)
15433{
15434 uint8_t val_u8;
15435
15436 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
15437 return;
15438 val_u8 = (value & 0xff000000) >> 24;
15439 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15440 val_u8 = (value & 0xff0000) >> 16;
15441 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15442 val_u8 = (value & 0xff00) >> 8;
15443 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15444 val_u8 = value & 0xff;
15445 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15446}
15447
15448/**
15449 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
15450 * @resp_type: Response type for mDNS
15451 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15452 *
15453 * This function will pack the response type, class and TTL (Time To Live).
15454 *
15455 * Return: Return boolean. TRUE for success, FALSE for fail.
15456 */
15457static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
15458 sir_mdns_resp_info resp_info)
15459{
15460 uint16_t len;
15461
15462 if (resp_info == NULL) {
15463 hddLog(LOGE, FL("resp_info is NULL!"));
15464 return FALSE;
15465 }
15466
15467 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
15468 if (len >= MAX_MDNS_RESP_LEN) {
15469 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15470 return FALSE;
15471 }
15472
15473 /* Fill Type, Class, TTL */
15474 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
15475 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
15476 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
15477
15478 return TRUE;
15479}
15480
15481/**
15482 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
15483 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15484 * @response_dst: The response which domain name is compressed.
15485 * @response_src: The response which domain name is matched with response_dst.
15486 * Its offset is used for data compression.
15487 * @num_matched: The number of matched entries between response_dst and
15488 * response_src
15489 *
15490 * This function will form the different fields of domain name in response_dst
15491 * if any. Then use the offset of the matched domain name in response_src to
15492 * compress the matched domain name.
15493 *
15494 * Return: Return boolean. TRUE for success, FALSE for fail.
15495 */
15496static bool
15497wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
15498 struct hdd_mdns_resp_info *response_dst,
15499 struct hdd_mdns_resp_info *response_src,
15500 uint8_t num_matched)
15501{
15502 uint8_t num, num_diff;
15503 uint16_t value, idx;
15504 uint8_t len = 0;
15505
15506 if ((response_src == NULL) || (response_dst == NULL) ||
15507 (resp_info == NULL)) {
15508 hddLog(LOGE, FL("response info is NULL!"));
15509 return FALSE;
15510 }
15511
15512 if (response_dst->num_entries < num_matched) {
15513 hddLog(LOGE, FL("num_entries is less than num_matched!"));
15514 return FALSE;
15515 }
15516
15517 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
15518 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15519 return FALSE;
15520 }
15521
15522 num_diff = response_dst->num_entries - num_matched;
15523 if ((num_diff > 0) && (response_dst->data == NULL)) {
15524 hddLog(LOGE, FL("response_dst->data is NULL!"));
15525 return FALSE;
15526 }
15527
15528 /*
15529 * Handle the unmatched string at the beginning
15530 * Store the length of octets and the octets
15531 */
15532 for (num = 0; num < num_diff; num++) {
15533 response_dst->offset[num] =
15534 resp_info->resp_len + MDNS_HEADER_LEN;
15535 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15536 len = strlen((char *)&response_dst->data[idx]);
15537 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
15538 hddLog(LOGE, FL("resp_len exceeds %d!"),
15539 MAX_MDNS_RESP_LEN);
15540 return FALSE;
15541 }
15542 resp_info->resp_data[resp_info->resp_len] = len;
15543 resp_info->resp_len++;
15544 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15545 &response_dst->data[idx], len);
15546 resp_info->resp_len += len;
15547 }
15548 /*
15549 * Handle the matched string from the end
15550 * Just keep the offset and mask the leading two bit
15551 */
15552 if (response_src->num_entries >= num_matched) {
15553 num_diff = response_src->num_entries - num_matched;
15554 value = response_src->offset[num_diff];
15555 if (value > 0) {
15556 value |= 0xc000;
15557 if ((resp_info->resp_len + sizeof(uint16_t)) >=
15558 MAX_MDNS_RESP_LEN) {
15559 hddLog(LOGE, FL("resp_len exceeds %d!"),
15560 MAX_MDNS_RESP_LEN);
15561 return FALSE;
15562 }
15563 wlan_hdd_mdns_format_response_u16(value, resp_info);
15564 return TRUE;
15565 }
15566 }
15567 return FALSE;
15568}
15569
15570/**
15571 * wlan_hdd_mdns_reset_response() - Reset the response info
15572 * @response: The response which info is reset.
15573 *
15574 * Return: None
15575 */
15576static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
15577{
15578 if (response == NULL)
15579 return;
15580 response->num_entries = 0;
15581 response->data = NULL;
15582 response->offset = NULL;
15583}
15584
15585/**
15586 * wlan_hdd_mdns_init_response() - Initialize the response info
15587 * @response: The response which info is initiatized.
15588 * @resp_dname: The domain name string which might be tokenized.
15589 *
15590 * This function will allocate the memory for both response->data and
15591 * response->offset. Besides, it will also tokenize the domain name to some
15592 * entries and fill response->num_entries with the num of entries.
15593 *
15594 * Return: Return boolean. TRUE for success, FALSE for fail.
15595 */
15596static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
15597 uint8_t *resp_dname, char separator)
15598{
15599 uint16_t size;
15600
15601 if ((resp_dname == NULL) || (response == NULL)) {
15602 hddLog(LOGE, FL("resp_dname or response is NULL!"));
15603 return FALSE;
15604 }
15605
15606 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
15607 response->data = vos_mem_malloc(size);
15608 if (response->data) {
15609 vos_mem_zero(response->data, size);
15610 if (VOS_STATUS_SUCCESS !=
15611 hdd_string_to_string_array((char *)resp_dname,
15612 response->data,
15613 separator,
15614 &response->num_entries,
15615 MAX_NUM_FIELD_DOMAINNAME,
15616 MAX_LEN_DOMAINNAME_FIELD)) {
15617 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
15618 goto err_init_resp;
15619 }
15620
15621 if ((response->num_entries > 0) &&
15622 (strlen((char *)&response->data[0]) > 0)) {
15623 size = sizeof(uint16_t) * response->num_entries;
15624 response->offset = vos_mem_malloc(size);
15625 if (response->offset) {
15626 vos_mem_zero(response->offset, size);
15627 return TRUE;
15628 }
15629 }
15630 }
15631
15632err_init_resp:
15633 if (response->data)
15634 vos_mem_free(response->data);
15635 wlan_hdd_mdns_reset_response(response);
15636 return FALSE;
15637}
15638
15639/**
15640 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
15641 * @response1: The response info is used to be compared.
15642 * @response2: The response info is used to be compared.
15643 *
15644 * This function will find the matched entries from the end.
15645 *
15646 * Return: Return the number of the matched entries.
15647 */
15648static uint8_t
15649wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
15650 struct hdd_mdns_resp_info *response2)
15651{
15652 uint8_t min, len1, i;
15653 uint16_t num1, num2;
15654 uint8_t num_matched = 0;
15655
15656 min = VOS_MIN(response1->num_entries, response2->num_entries);
15657
15658 for (i = 1; i <= min; i++) {
15659 num1 = (response1->num_entries - i);
15660 num1 *= MAX_LEN_DOMAINNAME_FIELD;
15661 num2 = (response2->num_entries - i);
15662 num2 *= MAX_LEN_DOMAINNAME_FIELD;
15663 len1 = strlen((char *)&response1->data[num1]);
15664
15665 if ((len1 == 0) ||
15666 (len1 != strlen((char *)&response2->data[num2])))
15667 break;
15668 if (memcmp(&response1->data[num1],
15669 &response2->data[num2], len1))
15670 break;
15671 else
15672 num_matched++;
15673 }
15674
15675 return num_matched;
15676}
15677
15678/**
15679 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
15680 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
15681 * @numlist: The number of the elements in the array matchedlist.
15682 *
15683 * Find the max number of the matched entries among the array matchedlist.
15684 *
15685 * Return: None
15686 */
15687static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
15688 uint8_t numlist)
15689{
15690 int j;
15691 struct hdd_mdns_resp_matched tmp;
15692
15693 /* At least two values are used for sorting */
15694 if ((numlist < 2) || (matchedlist == NULL)) {
15695 hddLog(LOGE, FL("At least two values are used for sorting!"));
15696 return;
15697 }
15698
15699 for (j = 0; j < numlist-1; j++) {
15700 if (matchedlist[j].num_matched >
15701 matchedlist[j+1].num_matched) {
15702 vos_mem_copy(&tmp, &matchedlist[j],
15703 sizeof(struct hdd_mdns_resp_matched));
15704 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
15705 sizeof(struct hdd_mdns_resp_matched));
15706 vos_mem_copy(&matchedlist[j+1], &tmp,
15707 sizeof(struct hdd_mdns_resp_matched));
15708 }
15709 }
15710}
15711
15712/**
15713 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
15714 * @ini_config: Pointer to the struct hdd_config_t
15715 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15716 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15717 *
15718 * Type A response include QName, response type, class, TTL and Ipv4.
15719 *
15720 * Return: Return boolean. TRUE for success, FALSE for fail.
15721 */
15722static bool
15723wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
15724 sir_mdns_resp_info resp_info,
15725 struct hdd_mdns_resp_info *resptype_a)
15726{
15727 uint16_t value;
15728 uint32_t len;
15729
15730 ENTER();
15731 if ((ini_config == NULL) || (resp_info == NULL) ||
15732 (resptype_a == NULL)) {
15733 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15734 return FALSE;
15735 }
15736
15737 /* No Type A response */
15738 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
15739 return TRUE;
15740
15741 /* Wrong response is assigned, just ignore this response */
15742 if (!wlan_hdd_mdns_init_response(resptype_a,
15743 ini_config->mdns_resp_type_a, '.'))
15744 return TRUE;
15745
15746 /* Process response domain name */
15747 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
15748 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15749 MDNS_TYPE_A);
15750 return FALSE;
15751 }
15752
15753 /* Process response Type, Class, TTL */
15754 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
15755 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
15756 MDNS_TYPE_A);
15757 return FALSE;
15758 }
15759
15760 /* Process response RDLength, RData */
15761 len = sizeof(uint16_t) + sizeof(uint32_t);
15762 len += resp_info->resp_len;
15763 if (len >= MAX_MDNS_RESP_LEN) {
15764 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15765 return FALSE;
15766 }
15767 value = sizeof(uint32_t);
15768 wlan_hdd_mdns_format_response_u16(value, resp_info);
15769 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
15770 resp_info);
15771
15772 EXIT();
15773 return TRUE;
15774}
15775
15776/**
15777 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
15778 * @ini_config: Pointer to the struct hdd_config_t
15779 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15780 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
15781 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15782 *
15783 * Type Txt response include QName, response type, class, TTL and text content.
15784 * Also, it will find the matched QName from resptype_A and compress the data.
15785 *
15786 * Return: Return boolean. TRUE for success, FALSE for fail.
15787 */
15788static bool
15789wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
15790 sir_mdns_resp_info resp_info,
15791 struct hdd_mdns_resp_info *resptype_txt,
15792 struct hdd_mdns_resp_info *resptype_a)
15793{
15794 uint8_t num_matched;
15795 uint8_t num;
15796 uint16_t idx;
15797 uint16_t value = 0;
15798 uint32_t len;
15799 uint32_t total_len;
15800 bool status;
15801 struct hdd_mdns_resp_info resptype_content;
15802
15803 ENTER();
15804
15805 if ((ini_config == NULL) || (resp_info == NULL) ||
15806 (resptype_txt == NULL)) {
15807 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15808 return FALSE;
15809 }
15810
15811 /* No Type Txt response */
15812 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
15813 return TRUE;
15814
15815 /* Wrong response is assigned, just ignore this response */
15816 if (!wlan_hdd_mdns_init_response(resptype_txt,
15817 ini_config->mdns_resp_type_txt, '.'))
15818 return TRUE;
15819
15820 /*
15821 * For data compression
15822 * Check if any strings are matched with Type A response
15823 */
15824 if (resptype_a && (resptype_a->num_entries > 0)) {
15825 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
15826 resptype_a);
15827 if (num_matched > 0) {
15828 if (!wlan_hdd_mdns_compress_data(resp_info,
15829 resptype_txt, resptype_a, num_matched)) {
15830 hddLog(LOGE, FL("Fail to compress mDNS "
15831 "response (%d)!"), MDNS_TYPE_TXT);
15832 return FALSE;
15833 }
15834 } else {
15835 /*
15836 * num_matched is zero. Error!
15837 * At least ".local" is needed.
15838 */
15839 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
15840 "response (%d)!"), MDNS_TYPE_TXT);
15841 return FALSE;
15842 }
15843 } else {
15844 /* no TypeA response, so show the whole data */
15845 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
15846 resp_info)) {
15847 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15848 MDNS_TYPE_TXT);
15849 return FALSE;
15850 }
15851 }
15852
15853 /* Process response Type, Class, TTL */
15854 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
15855 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
15856 MDNS_TYPE_TXT);
15857 return FALSE;
15858 }
15859
15860 /*
15861 * Process response RDLength, RData.
15862 * TypeTxt RData include len.
15863 */
15864 status = wlan_hdd_mdns_init_response(&resptype_content,
15865 ini_config->mdns_resp_type_txt_content,
15866 '/');
15867 if (status == FALSE) {
15868 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
15869 return FALSE;
15870 }
15871
15872 for (num = 0; num < resptype_content.num_entries; num++) {
15873 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15874 value += strlen((char *)&resptype_content.data[idx]);
15875 }
15876
15877 /* content len is uint16_t */
15878 total_len = sizeof(uint16_t);
15879 total_len += resp_info->resp_len + value +
15880 resptype_content.num_entries;
15881
15882 if (total_len >= MAX_MDNS_RESP_LEN) {
15883 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15884 return FALSE;
15885 }
15886 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
15887 resp_info);
15888
15889 for (num = 0; num < resptype_content.num_entries; num++) {
15890 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15891 len = strlen((char *)&resptype_content.data[idx]);
15892 resp_info->resp_data[resp_info->resp_len] = len;
15893 resp_info->resp_len++;
15894
15895 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15896 &resptype_content.data[idx], len);
15897
15898 resp_info->resp_len += len;
15899 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
15900 num, len, &resptype_content.data[idx]);
15901 }
15902
15903 EXIT();
15904 return TRUE;
15905}
15906
15907/**
15908 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
15909 * @ini_config: Pointer to the struct hdd_config_t
15910 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15911 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15912 * domain name
15913 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15914 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
15915 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15916 *
15917 * The Type Ptr response include Type PTR domain name in its data field.
15918 * Also, it will find the matched QName from the existing resptype_ptr,
15919 * resptype_txt, resptype_a and then compress the data.
15920 *
15921 * Return: Return boolean. TRUE for success, FALSE for fail.
15922 */
15923static bool
15924wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
15925 sir_mdns_resp_info resp_info,
15926 struct hdd_mdns_resp_info *resptype_ptr_dn,
15927 struct hdd_mdns_resp_info *resptype_ptr,
15928 struct hdd_mdns_resp_info *resptype_txt,
15929 struct hdd_mdns_resp_info *resptype_a)
15930{
15931 uint8_t num_matched, numlist, size;
15932 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
15933 struct hdd_mdns_resp_info *resp;
15934
15935 if ((ini_config == NULL) || (resp_info == NULL) ||
15936 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
15937 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15938 return FALSE;
15939 }
15940
15941 /* No Type Ptr domain name response */
15942 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
15943 return TRUE;
15944
15945 /* Wrong response is assigned, just ignore this response */
15946 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
15947 ini_config->mdns_resp_type_ptr_dname, '.'))
15948 return TRUE;
15949
15950 /*
15951 * For data compression
15952 * Check if any strings are matched with previous
15953 * response.
15954 */
15955 numlist = 0;
15956 size = (MAX_MDNS_RESP_TYPE-1);
15957 size *= sizeof(struct hdd_mdns_resp_matched);
15958 vos_mem_zero(matchedlist, size);
15959 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
15960 resptype_ptr);
15961 if (num_matched > 0) {
15962 matchedlist[numlist].num_matched = num_matched;
15963 matchedlist[numlist].type = MDNS_TYPE_PTR;
15964 numlist++;
15965 }
15966 if (resptype_txt && (resptype_txt->num_entries > 0)) {
15967 num_matched = wlan_hdd_mdns_find_entries_from_end(
15968 resptype_ptr_dn, resptype_txt);
15969 if (num_matched > 0) {
15970 matchedlist[numlist].num_matched = num_matched;
15971 matchedlist[numlist].type = MDNS_TYPE_TXT;
15972 numlist++;
15973 }
15974 }
15975 if (resptype_a && (resptype_a->num_entries > 0)) {
15976 num_matched = wlan_hdd_mdns_find_entries_from_end(
15977 resptype_ptr_dn,resptype_a);
15978 if (num_matched > 0) {
15979 matchedlist[numlist].num_matched = num_matched;
15980 matchedlist[numlist].type = MDNS_TYPE_A;
15981 numlist++;
15982 }
15983 }
15984 if (numlist > 0) {
15985 if (numlist > 1)
15986 wlan_hdd_mdns_find_max(matchedlist, numlist);
15987 resp = NULL;
15988 switch (matchedlist[numlist-1].type) {
15989 case MDNS_TYPE_A:
15990 resp = resptype_a;
15991 break;
15992 case MDNS_TYPE_TXT:
15993 resp = resptype_txt;
15994 break;
15995 case MDNS_TYPE_PTR:
15996 resp = resptype_ptr;
15997 break;
15998 default:
15999 hddLog(LOGE, FL("Fail to compress mDNS response "
16000 "(%d)!"), MDNS_TYPE_PTR_DNAME);
16001 return FALSE;
16002 }
16003 num_matched = matchedlist[numlist-1].num_matched;
16004 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
16005 resp, num_matched)) {
16006 hddLog(LOGE, FL("Fail to compress mDNS response "
16007 "(%d)!"), MDNS_TYPE_PTR_DNAME);
16008 return FALSE;
16009 }
16010 } else {
16011 /* num = 0 -> no matched string */
16012 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
16013 resp_info)) {
16014 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16015 MDNS_TYPE_PTR_DNAME);
16016 return FALSE;
16017 }
16018 }
16019
16020 return TRUE;
16021}
16022
16023/**
16024 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
16025 * @ini_config: Pointer to the struct hdd_config_t
16026 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16027 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16028 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16029 * domain name
16030 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16031 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16032 *
16033 * The Type Ptr response include QName, response type, class, TTL and
16034 * Type PTR domain name. Also, it will find the matched QName from the
16035 * existing resptype_txt, resptype_a and then compress the data.
16036 *
16037 * Return: Return boolean. TRUE for success, FALSE for fail.
16038 */
16039static bool
16040wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
16041 sir_mdns_resp_info resp_info,
16042 struct hdd_mdns_resp_info *resptype_ptr,
16043 struct hdd_mdns_resp_info *resptype_ptr_dn,
16044 struct hdd_mdns_resp_info *resptype_txt,
16045 struct hdd_mdns_resp_info *resptype_a)
16046{
16047 uint8_t num_matched, num_matched1;
16048 uint16_t value;
16049 uint8_t val_u8;
16050 uint32_t offset_data_len, len;
16051
16052 ENTER();
16053 if ((ini_config == NULL) || (resp_info == NULL) ||
16054 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
16055 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16056 return FALSE;
16057 }
16058
16059 /* No Type Ptr response */
16060 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
16061 return TRUE;
16062
16063 /* Wrong response is assigned, just ignore this response */
16064 if (!wlan_hdd_mdns_init_response(resptype_ptr,
16065 ini_config->mdns_resp_type_ptr, '.'))
16066 return TRUE;
16067
16068 /*
16069 * For data compression
16070 * Check if any strings are matched with Type A response
16071 */
16072 num_matched = 0;
16073 num_matched1 = 0;
16074 if (resptype_a && (resptype_a->num_entries > 0)) {
16075 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
16076 resptype_a);
16077 }
16078 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16079 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
16080 resptype_ptr, resptype_txt);
16081 }
16082 if ((num_matched != num_matched1) ||
16083 ((num_matched > 0) && (num_matched1 > 0))) {
16084 if (num_matched >= num_matched1) {
16085 if (!wlan_hdd_mdns_compress_data(resp_info,
16086 resptype_ptr, resptype_a, num_matched)) {
16087 hddLog(LOGE, FL("Fail to compress mDNS "
16088 "response (%d)!"), MDNS_TYPE_PTR);
16089 return FALSE;
16090 }
16091 } else {
16092 /* num_matched is less than num_matched1 */
16093 if (!wlan_hdd_mdns_compress_data(resp_info,
16094 resptype_ptr, resptype_txt, num_matched1)) {
16095 hddLog(LOGE, FL("Fail to compress mDNS "
16096 "response (%d)!"), MDNS_TYPE_PTR);
16097 return FALSE;
16098 }
16099 }
16100 } else {
16101 /*
16102 * Both num_matched and num_matched1 are zero.
16103 * no TypeA & TypeTxt
16104 */
16105 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
16106 resp_info)) {
16107 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16108 MDNS_TYPE_PTR);
16109 return FALSE;
16110 }
16111 }
16112
16113 /* Process response Type, Class, TTL */
16114 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
16115 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16116 MDNS_TYPE_PTR);
16117 return FALSE;
16118 }
16119
16120 /*
16121 * Process response RDLength, RData (Ptr domain name)
16122 * Save the offset of RData length
16123 */
16124 offset_data_len = resp_info->resp_len;
16125 resp_info->resp_len += sizeof(uint16_t);
16126
16127 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
16128 resptype_ptr_dn, resptype_ptr,
16129 resptype_txt, resptype_a)) {
16130 return FALSE;
16131 }
16132 /* Set the RData length */
16133 len = offset_data_len + sizeof(uint16_t);
16134 if ((resptype_ptr_dn->num_entries > 0) &&
16135 (resp_info->resp_len > len)) {
16136 value = resp_info->resp_len - len;
16137 val_u8 = (value & 0xff00) >> 8;
16138 resp_info->resp_data[offset_data_len] = val_u8;
16139 val_u8 = value & 0xff;
16140 resp_info->resp_data[offset_data_len+1] = val_u8;
16141 } else {
16142 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16143 MDNS_TYPE_PTR);
16144 return FALSE;
16145 }
16146
16147 EXIT();
16148 return TRUE;
16149}
16150
16151/**
16152 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
16153 * @ini_config: Pointer to the struct hdd_config_t
16154 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16155 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
16156 * target
16157 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
16158 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16159 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16160 * domain name
16161 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16162 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16163 *
16164 * The Type service target is one of the data field in the Type SRV response.
16165 * Also, it will find the matched QName from the existing resptype_srv,
16166 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
16167 * the data.
16168 *
16169 * Return: Return boolean. TRUE for success, FALSE for fail.
16170 */
16171static bool
16172wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
16173 sir_mdns_resp_info resp_info,
16174 struct hdd_mdns_resp_info *resptype_srv_tgt,
16175 struct hdd_mdns_resp_info *resptype_srv,
16176 struct hdd_mdns_resp_info *resptype_ptr,
16177 struct hdd_mdns_resp_info *resptype_ptr_dn,
16178 struct hdd_mdns_resp_info *resptype_txt,
16179 struct hdd_mdns_resp_info *resptype_a)
16180{
16181 uint8_t num_matched, num, size;
16182 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
16183 struct hdd_mdns_resp_info *resp;
16184
16185 if ((ini_config == NULL) || (resp_info == NULL) ||
16186 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
16187 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16188 return FALSE;
16189 }
16190
16191 /* No Type Srv Target response */
16192 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
16193 return TRUE;
16194
16195 /* Wrong response is assigned, just ignore this response */
16196 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
16197 ini_config->mdns_resp_type_srv_target, '.'))
16198 return TRUE;
16199
16200 /*
16201 * For data compression
16202 * Check if any strings are matched with previous response.
16203 */
16204 num = 0;
16205 size = (MAX_MDNS_RESP_TYPE-1);
16206 size *= sizeof(struct hdd_mdns_resp_matched);
16207 vos_mem_zero(matchedlist, size);
16208 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
16209 resptype_srv);
16210 if (num_matched > 0) {
16211 matchedlist[num].num_matched = num_matched;
16212 matchedlist[num].type = MDNS_TYPE_SRV;
16213 num++;
16214 }
16215 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
16216 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
16217 num_matched = wlan_hdd_mdns_find_entries_from_end(
16218 resptype_srv_tgt, resptype_ptr_dn);
16219 if (num_matched > 0) {
16220 matchedlist[num].num_matched = num_matched;
16221 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
16222 num++;
16223 }
16224 }
16225 num_matched = wlan_hdd_mdns_find_entries_from_end(
16226 resptype_srv_tgt, resptype_ptr);
16227 if (num_matched > 0) {
16228 matchedlist[num].num_matched = num_matched;
16229 matchedlist[num].type = MDNS_TYPE_PTR;
16230 num++;
16231 }
16232 }
16233 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16234 num_matched = wlan_hdd_mdns_find_entries_from_end(
16235 resptype_srv_tgt, resptype_txt);
16236 if (num_matched > 0) {
16237 matchedlist[num].num_matched = num_matched;
16238 matchedlist[num].type = MDNS_TYPE_TXT;
16239 num++;
16240 }
16241 }
16242 if (resptype_a && (resptype_a->num_entries > 0)) {
16243 num_matched = wlan_hdd_mdns_find_entries_from_end(
16244 resptype_srv_tgt, resptype_a);
16245 if (num_matched > 0) {
16246 matchedlist[num].num_matched = num_matched;
16247 matchedlist[num].type = MDNS_TYPE_A;
16248 num++;
16249 }
16250 }
16251 if (num > 0) {
16252 if (num > 1)
16253 wlan_hdd_mdns_find_max(matchedlist, num);
16254 resp = NULL;
16255 switch (matchedlist[num-1].type) {
16256 case MDNS_TYPE_A:
16257 resp = resptype_a;
16258 break;
16259 case MDNS_TYPE_TXT:
16260 resp = resptype_txt;
16261 break;
16262 case MDNS_TYPE_PTR:
16263 resp = resptype_ptr;
16264 break;
16265 case MDNS_TYPE_PTR_DNAME:
16266 resp = resptype_ptr_dn;
16267 break;
16268 case MDNS_TYPE_SRV:
16269 resp = resptype_srv;
16270 break;
16271 default:
16272 hddLog(LOGE, FL("Fail to compress mDNS response "
16273 "(%d)!"), MDNS_TYPE_SRV_TARGET);
16274 return FALSE;
16275 }
16276 num_matched = matchedlist[num-1].num_matched;
16277 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
16278 resp, num_matched)) {
16279 hddLog(LOGE, FL("Fail to compress mDNS response "
16280 "(%d)!"), MDNS_TYPE_SRV_TARGET);
16281 return FALSE;
16282 }
16283 } else {
16284 /* num = 0 -> no matched string */
16285 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
16286 resp_info)) {
16287 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16288 MDNS_TYPE_SRV_TARGET);
16289 return FALSE;
16290 }
16291 }
16292
16293 return TRUE;
16294}
16295
16296/**
16297 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
16298 * @ini_config: Pointer to the struct hdd_config_t
16299 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16300 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
16301 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
16302 * target
16303 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16304 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16305 * domain name
16306 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16307 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16308 *
16309 * The Type SRV (Service) response include QName, response type, class, TTL
16310 * and four kinds of data fields. Also, it will find the matched QName from
16311 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
16312 * then compress the data.
16313 *
16314 * Return: Return boolean. TRUE for success, FALSE for fail.
16315 */
16316static bool
16317wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
16318 sir_mdns_resp_info resp_info,
16319 struct hdd_mdns_resp_info *resptype_srv,
16320 struct hdd_mdns_resp_info *resptype_srv_tgt,
16321 struct hdd_mdns_resp_info *resptype_ptr,
16322 struct hdd_mdns_resp_info *resptype_ptr_dn,
16323 struct hdd_mdns_resp_info *resptype_txt,
16324 struct hdd_mdns_resp_info *resptype_a)
16325{
16326 uint8_t num_matched, num, size;
16327 uint16_t value;
16328 uint8_t val_u8;
16329 uint32_t offset_data_len, len;
16330 struct hdd_mdns_resp_info *resp;
16331 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
16332
16333 ENTER();
16334
16335 if ((ini_config == NULL) || (resp_info == NULL) ||
16336 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
16337 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16338 return FALSE;
16339 }
16340
16341 /* No Type Srv response */
16342 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
16343 return TRUE;
16344
16345 /* Wrong response is assigned, just ignore this response */
16346 if (!wlan_hdd_mdns_init_response(resptype_srv,
16347 ini_config->mdns_resp_type_srv, '.'))
16348 return TRUE;
16349
16350 /*
16351 * For data compression
16352 * Check if any strings are matched with Type A response
16353 */
16354 num = 0;
16355 size = (MAX_MDNS_RESP_TYPE-1);
16356 size *= sizeof(struct hdd_mdns_resp_matched);
16357 vos_mem_zero(matchedlist, size);
16358 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
16359 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
16360 num_matched = wlan_hdd_mdns_find_entries_from_end(
16361 resptype_srv,
16362 resptype_ptr_dn);
16363 if (num_matched > 0) {
16364 matchedlist[num].num_matched = num_matched;
16365 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
16366 num++;
16367 }
16368 }
16369 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16370 resptype_ptr);
16371 if (num_matched > 0) {
16372 matchedlist[num].num_matched = num_matched;
16373 matchedlist[num].type = MDNS_TYPE_PTR;
16374 num++;
16375 }
16376 }
16377 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16378 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16379 resptype_txt);
16380 if (num_matched > 0) {
16381 matchedlist[num].num_matched =num_matched;
16382 matchedlist[num].type = MDNS_TYPE_TXT;
16383 num++;
16384 }
16385 }
16386 if (resptype_a && (resptype_a->num_entries > 0)) {
16387 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16388 resptype_a);
16389 if (num_matched > 0) {
16390 matchedlist[num].num_matched = num_matched;
16391 matchedlist[num].type = MDNS_TYPE_A;
16392 num++;
16393 }
16394 }
16395 if (num > 0) {
16396 if (num > 1)
16397 wlan_hdd_mdns_find_max(matchedlist, num);
16398 resp = NULL;
16399 switch (matchedlist[num-1].type) {
16400 case MDNS_TYPE_A:
16401 resp = resptype_a;
16402 break;
16403 case MDNS_TYPE_TXT:
16404 resp = resptype_txt;
16405 break;
16406 case MDNS_TYPE_PTR:
16407 resp = resptype_ptr;
16408 break;
16409 case MDNS_TYPE_PTR_DNAME:
16410 resp = resptype_ptr_dn;
16411 break;
16412 default:
16413 hddLog(LOGE, FL("Fail to compress mDNS response "
16414 "(%d)!"), MDNS_TYPE_SRV);
16415 return FALSE;
16416 }
16417 num_matched = matchedlist[num-1].num_matched;
16418 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
16419 resp, num_matched)) {
16420 hddLog(LOGE, FL("Fail to compress mDNS response "
16421 "(%d)!"), MDNS_TYPE_SRV);
16422 return FALSE;
16423 }
16424 } else {
16425 /* num = 0 -> no matched string */
16426 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
16427 resp_info)) {
16428 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16429 MDNS_TYPE_SRV);
16430 return FALSE;
16431 }
16432 }
16433
16434 /* Process response Type, Class, TTL */
16435 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
16436 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16437 MDNS_TYPE_SRV);
16438 return FALSE;
16439 }
16440
16441 /*
16442 * Process response RDLength, RData (Srv target name)
16443 * Save the offset of RData length
16444 */
16445 offset_data_len = resp_info->resp_len;
16446 resp_info->resp_len += sizeof(uint16_t);
16447
16448 len = resp_info->resp_len + (3 * sizeof(uint16_t));
16449 if (len >= MAX_MDNS_RESP_LEN) {
16450 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16451 return FALSE;
16452 }
16453
16454 /* set Srv Priority */
16455 value = ini_config->mdns_resp_type_srv_priority;
16456 wlan_hdd_mdns_format_response_u16(value, resp_info);
16457 /* set Srv Weight */
16458 value = ini_config->mdns_resp_type_srv_weight;
16459 wlan_hdd_mdns_format_response_u16(value, resp_info);
16460 /* set Srv Port */
16461 value = ini_config->mdns_resp_type_srv_port;
16462 wlan_hdd_mdns_format_response_u16(value, resp_info);
16463
16464 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
16465 resptype_srv_tgt, resptype_srv,
16466 resptype_ptr, resptype_ptr_dn,
16467 resptype_txt, resptype_a)) {
16468 return FALSE;
16469 }
16470 /* Set the RData length */
16471 len = offset_data_len + sizeof(uint16_t);
16472 if ((resptype_srv_tgt->num_entries > 0) &&
16473 (resp_info->resp_len > len)) {
16474 value = resp_info->resp_len - len;
16475 val_u8 = (value & 0xff00) >> 8;
16476 resp_info->resp_data[offset_data_len] = val_u8;
16477 val_u8 = value & 0xff;
16478 resp_info->resp_data[offset_data_len+1] = val_u8;
16479 } else {
16480 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16481 MDNS_TYPE_SRV);
16482 return FALSE;
16483 }
16484
16485 EXIT();
16486 return TRUE;
16487}
16488
16489/**
16490 * wlan_hdd_mdns_free_mem() - Free the allocated memory
16491 * @response: Pointer to the struct hdd_mdns_resp_info
16492 *
16493 * Return: None
16494 */
16495static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
16496{
16497 if (response && response->data)
16498 vos_mem_free(response->data);
16499 if (response && response->offset)
16500 vos_mem_free(response->offset);
16501}
16502
16503/**
16504 * wlan_hdd_mdns_pack_response() - Pack mDNS response
16505 * @ini_config: Pointer to the struct hdd_config_t
16506 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16507 *
16508 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
16509 * and Type Service). Each response contains QName, response type, class, TTL
16510 * and data fields.
16511 *
16512 * Return: Return boolean. TRUE for success, FALSE for fail.
16513 */
16514static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
16515 sir_mdns_resp_info resp_info)
16516{
16517 struct hdd_mdns_resp_info resptype_a, resptype_txt;
16518 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
16519 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
16520 uint32_t num_res_records = 0;
16521 bool status = FALSE;
16522
16523 ENTER();
16524
16525 wlan_hdd_mdns_reset_response(&resptype_a);
16526 wlan_hdd_mdns_reset_response(&resptype_txt);
16527 wlan_hdd_mdns_reset_response(&resptype_ptr);
16528 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
16529 wlan_hdd_mdns_reset_response(&resptype_srv);
16530 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
16531
16532 resp_info->resp_len = 0;
16533
16534 /* Process Type A response */
16535 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
16536 &resptype_a))
16537 goto err_resptype_a;
16538
16539 if ((resptype_a.num_entries > 0) &&
16540 (strlen((char *)&resptype_a.data[0]) > 0))
16541 num_res_records++;
16542
16543 /* Process Type TXT response */
16544 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
16545 &resptype_txt, &resptype_a))
16546 goto err_resptype_txt;
16547
16548 if ((resptype_txt.num_entries > 0) &&
16549 (strlen((char *)&resptype_txt.data[0]) > 0))
16550 num_res_records++;
16551
16552 /* Process Type PTR response */
16553 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
16554 &resptype_ptr, &resptype_ptr_dn,
16555 &resptype_txt, &resptype_a))
16556 goto err_resptype_ptr;
16557
16558 if ((resptype_ptr.num_entries > 0) &&
16559 (strlen((char *)&resptype_ptr.data[0]) > 0))
16560 num_res_records++;
16561
16562 /* Process Type SRV response */
16563 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
16564 &resptype_srv, &resptype_srv_tgt,
16565 &resptype_ptr, &resptype_ptr_dn,
16566 &resptype_txt, &resptype_a))
16567 goto err_resptype_srv;
16568
16569 if ((resptype_srv.num_entries > 0) &&
16570 (strlen((char *)&resptype_srv.data[0]) > 0))
16571 num_res_records++;
16572
16573 resp_info->resourceRecord_count = num_res_records;
16574 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
16575 "%s: Pack mDNS response data successfully!", __func__);
16576 status = TRUE;
16577
16578err_resptype_srv:
16579 wlan_hdd_mdns_free_mem(&resptype_srv);
16580 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
16581
16582err_resptype_ptr:
16583 wlan_hdd_mdns_free_mem(&resptype_ptr);
16584 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
16585
16586err_resptype_txt:
16587 wlan_hdd_mdns_free_mem(&resptype_txt);
16588
16589err_resptype_a:
16590 wlan_hdd_mdns_free_mem(&resptype_a);
16591
16592 EXIT();
16593 return status;
16594}
16595
16596/**
16597 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
16598 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
16599 *
16600 * This function will set FQDN/unique FQDN (full qualified domain name)
16601 * and the mDNS response. Then send them to SME.
16602 *
16603 * Return: Return boolean. TRUE for success, FALSE for fail.
16604 */
16605bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
16606{
16607 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
16608 sir_mdns_offload_info mdns_offload_info;
16609 sir_mdns_fqdn_info mdns_fqdn_info;
16610 sir_mdns_resp_info mdns_resp_info;
16611 uint32_t fqdn_len, ufqdn_len;
16612
16613 ENTER();
16614
16615 /* 1. Prepare the MDNS fqdn request to send to SME */
16616 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
16617 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
16618 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
16619 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
16620 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
16621 return FALSE;
16622 }
16623
16624 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
16625 if (NULL == mdns_fqdn_info) {
16626 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
16627 return FALSE;
16628 }
16629 /* MDNS fqdn request */
16630 if (fqdn_len > 0) {
16631 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
16632 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
16633 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
16634 mdns_fqdn_info->fqdn_len = fqdn_len;
16635 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
16636 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
16637 vos_mem_copy(mdns_fqdn_info->fqdn_data,
16638 hdd_ctx->cfg_ini->mdns_fqdn,
16639 mdns_fqdn_info->fqdn_len);
16640
16641 if (eHAL_STATUS_SUCCESS !=
16642 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
16643 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
16644 vos_mem_free(mdns_fqdn_info);
16645 return FALSE;
16646 }
16647 }
16648 /* MDNS unique fqdn request */
16649 if (ufqdn_len > 0) {
16650 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
16651 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
16652 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
16653 mdns_fqdn_info->fqdn_len = ufqdn_len;
16654 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
16655 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
16656 vos_mem_copy(mdns_fqdn_info->fqdn_data,
16657 hdd_ctx->cfg_ini->mdns_uniquefqdn,
16658 mdns_fqdn_info->fqdn_len);
16659 if (eHAL_STATUS_SUCCESS !=
16660 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
16661 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
16662 vos_mem_free(mdns_fqdn_info);
16663 return FALSE;
16664 }
16665 }
16666 vos_mem_free(mdns_fqdn_info);
16667
16668 /* 2. Prepare the MDNS response request to send to SME */
16669 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
16670 if (NULL == mdns_resp_info) {
16671 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
16672 return FALSE;
16673 }
16674
16675 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
16676 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
16677 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
16678 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
16679 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
16680 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
16681 vos_mem_free(mdns_resp_info);
16682 return FALSE;
16683 }
16684 if (eHAL_STATUS_SUCCESS !=
16685 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
16686 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
16687 vos_mem_free(mdns_resp_info);
16688 return FALSE;
16689 }
16690 vos_mem_free(mdns_resp_info);
16691
16692 /* 3. Prepare the MDNS Enable request to send to SME */
16693 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
16694 if (NULL == mdns_offload_info) {
16695 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
16696 return FALSE;
16697 }
16698
16699 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
16700
16701 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
16702 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
16703 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
16704 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
16705 if (eHAL_STATUS_SUCCESS !=
16706 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
16707 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
16708 vos_mem_free(mdns_offload_info);
16709 return FALSE;
16710 }
16711
16712 vos_mem_free(mdns_offload_info);
16713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
16714 "%s: enable mDNS offload successfully!", __func__);
16715 return TRUE;
16716}
Manjeet Singh3ed79242017-01-11 19:04:32 +053016717
16718
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016719#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053016720
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053016721/**
16722 * wlan_hdd_start_sap() - This function starts bss of SAP.
16723 * @ap_adapter: SAP adapter
16724 *
16725 * This function will process the starting of sap adapter.
16726 *
16727 * Return: void.
16728 */
16729void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
16730{
16731 hdd_ap_ctx_t *hdd_ap_ctx;
16732 hdd_hostapd_state_t *hostapd_state;
16733 VOS_STATUS vos_status;
16734 hdd_context_t *hdd_ctx;
16735 tsap_Config_t *pConfig;
16736
16737 if (NULL == ap_adapter) {
16738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16739 FL("ap_adapter is NULL here"));
16740 return;
16741 }
16742
16743 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
16744 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
16745 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
16746 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
16747
16748 mutex_lock(&hdd_ctx->sap_lock);
16749 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
16750 goto end;
16751
16752 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
16753 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
16754 goto end;
16755 }
16756
16757 vos_event_reset(&hostapd_state->vosEvent);
16758 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
16759 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
16760 != VOS_STATUS_SUCCESS) {
16761 goto end;
16762 }
16763
16764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16765 FL("Waiting for SAP to start"));
16766 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
16767 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
16768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16769 FL("SAP Start failed"));
16770 goto end;
16771 }
16772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16773 FL("SAP Start Success"));
16774 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
16775
16776 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
16777 hostapd_state->bCommit = TRUE;
16778
16779end:
16780 mutex_unlock(&hdd_ctx->sap_lock);
16781 return;
16782}
16783
Manjeet Singh3ed79242017-01-11 19:04:32 +053016784#ifdef WLAN_FEATURE_TSF
16785
16786/**
16787 * hdd_tsf_cb() - handle tsf request callback
16788 *
16789 * @pcb_cxt: pointer to the hdd_contex
16790 * @ptsf: pointer to struct stsf
16791 *
16792 * Based on the request sent .
16793 *
16794 * Return: Describe the execute result of this routine
16795 */
16796static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
16797{
16798 hdd_context_t *hddctx;
16799 int status;
16800 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
16801
16802 if (pcb_ctx == NULL || ptsf == NULL) {
16803 hddLog(VOS_TRACE_LEVEL_ERROR,
16804 FL("HDD context is not valid"));
16805 return -EINVAL;
16806 }
16807
16808 hddctx = (hdd_context_t *)pcb_ctx;
16809 status = wlan_hdd_validate_context(hddctx);
16810 if (0 != status)
16811 return -EINVAL;
16812
16813 if (NULL == adapter) {
16814 hddLog(VOS_TRACE_LEVEL_ERROR,
16815 FL("failed to find adapter"));
16816 return -EINVAL;
16817 }
16818
16819 hddLog(VOS_TRACE_LEVEL_INFO,
16820 FL("tsf cb handle event, device_mode is %d"),
16821 adapter->device_mode);
16822
16823 /* copy the return value to hdd_tsf_ctx in adapter*/
16824 if (ptsf->tsf_req_status) {
16825
16826 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16827 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
16828 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16829 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
16830 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16831
16832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
16833 ptsf->tsf_req_status);
16834 return ptsf->tsf_req_status;
16835 }
16836 /* If this is a get request.Store the tsf values in adapter. */
16837 if (!ptsf->set_tsf_req) {
16838 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16839 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
16840 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
16841 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
16842 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16843 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16844
16845 hddLog(VOS_TRACE_LEVEL_INFO,
16846 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
16847 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
16848 }
16849 else {
16850 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16851 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
16852 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
16853 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16854 }
16855 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16856 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
16857 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16858
16859 /* free allocated mem */
16860 vos_mem_free(ptsf);
16861
16862 return 0;
16863}
16864
16865/**
16866 * hdd_capture_tsf() - capture tsf
16867 *
16868 * @adapter: pointer to adapter
16869 * @buf: pointer to upper layer buf
16870 * @len : the length of buf
16871 *
16872 * This function returns tsf value to uplayer.
16873 *
16874 * Return: Describe the execute result of this routine
16875 */
16876int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
16877{
16878 int ret = 0;
16879 hdd_station_ctx_t *hdd_sta_ctx;
16880 hdd_context_t *hdd_ctx;
16881 tSirCapTsfParams cap_tsf_params;
16882 VOS_STATUS status;
16883
16884 if (adapter == NULL || buf == NULL) {
16885 hddLog(VOS_TRACE_LEVEL_ERROR,
16886 FL("invalid pointer"));
16887 return -EINVAL;
16888 }
16889 if (len != 1)
16890 return -EINVAL;
16891
16892 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16893
16894 if (wlan_hdd_validate_context(hdd_ctx)) {
16895 hddLog(VOS_TRACE_LEVEL_ERROR,
16896 FL("invalid hdd ctx"));
16897 return -EINVAL;
16898 }
16899 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
16900 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
16901 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
16902 if (hdd_sta_ctx->conn_info.connState !=
16903 eConnectionState_Associated) {
16904
16905 hddLog(VOS_TRACE_LEVEL_INFO,
16906 FL("failed to cap tsf, not connect with ap"));
16907 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
16908 return ret;
16909 }
16910 }
16911 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
16912 adapter->device_mode == WLAN_HDD_P2P_GO) &&
16913 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
16914 hddLog(VOS_TRACE_LEVEL_INFO,
16915 FL("Soft AP / P2p GO not beaconing"));
16916 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
16917 return ret;
16918 }
16919 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
16920 hddLog(VOS_TRACE_LEVEL_INFO,
16921 FL("current in capture state, pls reset"));
16922 buf[0] = TSF_CURRENT_IN_CAP_STATE;
16923 } else {
16924 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
16925 buf[0] = TSF_RETURN;
16926 cap_tsf_params.session_id = adapter->sessionId;
16927 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
16928 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
16929
16930 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16931 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
16932 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
16933 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16934
16935 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
16936
16937 if (ret != VOS_STATUS_SUCCESS) {
16938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
16939 buf[0] = TSF_CAPTURE_FAIL;
16940 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16941 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16942 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16943 return -EINVAL;
16944 }
16945 /* wait till we get a response from fw */
16946 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
16947 tsf_capture_done_event,
16948 HDD_TSF_CAP_REQ_TIMEOUT);
16949
16950 if (!VOS_IS_STATUS_SUCCESS(status)) {
16951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16952 ("capture tsf vos wait for single_event failed!! %d"),
16953 adapter->tsf_cap_ctx.tsf_get_state);
16954
16955 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16956 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16957 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16958
16959 return -EINVAL;
16960 }
16961 }
16962 buf[0] = TSF_RETURN;
16963 hddLog(VOS_TRACE_LEVEL_INFO,
16964 FL("ioctl return cap tsf cmd, ret = %d"), ret);
16965 return ret;
16966}
16967
16968/**
16969 * hdd_indicate_tsf() - return tsf to uplayer
16970 *
16971 * @adapter: pointer to adapter
16972 * @buf: pointer to uplayer buf
16973 * @len : the length of buf
16974 *
16975 * This function returns tsf value to uplayer.
16976 *
16977 * Return: Describe the execute result of this routine
16978 */
16979int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
16980{
16981 int ret = 0;
16982 hdd_station_ctx_t *hdd_sta_ctx;
16983 hdd_context_t *hdd_ctx;
16984 tSirCapTsfParams cap_tsf_params;
16985 VOS_STATUS status;
16986
16987 if (adapter == NULL || buf == NULL) {
16988 hddLog(VOS_TRACE_LEVEL_ERROR,
16989 FL("invalid pointer"));
16990 return -EINVAL;
16991 }
16992 if (len != 3)
16993 return -EINVAL;
16994
16995 buf [1] = 0;
16996 buf [2] = 0;
16997 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16998
16999 if (wlan_hdd_validate_context(hdd_ctx)) {
17000 hddLog(VOS_TRACE_LEVEL_ERROR,
17001 FL("invalid hdd ctx"));
17002 return -EINVAL;
17003 }
17004 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
17005 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
17006 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
17007 if (hdd_sta_ctx->conn_info.connState !=
17008 eConnectionState_Associated) {
17009
17010 hddLog(VOS_TRACE_LEVEL_INFO,
17011 FL("failed to cap tsf, not connect with ap"));
17012 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
17013 return ret;
17014 }
17015 }
17016 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
17017 adapter->device_mode == WLAN_HDD_P2P_GO) &&
17018 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
17019 hddLog(VOS_TRACE_LEVEL_INFO,
17020 FL("Soft AP / P2p GO not beaconing"));
17021 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
17022 return ret;
17023 }
17024
17025 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
17026 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
17027 hddLog(VOS_TRACE_LEVEL_INFO,
17028 FL("Not in capture state,Enter capture state first"));
17029 buf[0] = TSF_GET_FAIL;
17030 } else {
17031 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
17032 cap_tsf_params.session_id = adapter->sessionId;
17033 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
17034 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
17035
17036 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
17037
17038 if (ret != VOS_STATUS_SUCCESS) {
17039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
17040 buf[0] = TSF_CAPTURE_FAIL;
17041 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17042 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17043 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17044 return -EINVAL;
17045 }
17046 /* wait till we get a response from fw */
17047 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
17048 tsf_capture_done_event,
17049 HDD_TSF_GET_REQ_TIMEOUT);
17050
17051 if (!VOS_IS_STATUS_SUCCESS(status)) {
17052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17053 ("capture tsf vos wait for single_event failed!! %d"),
17054 status);
17055
17056 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17057 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17058 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17059 return status;
17060 }
17061 buf[1] = adapter->tsf_cap_ctx.tsf_low;
17062 buf[2] = adapter->tsf_cap_ctx.tsf_high;
17063
17064 hddLog(VOS_TRACE_LEVEL_INFO,
17065 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
17066 buf[0], buf[1], buf[2]);
17067 }
17068 hddLog(VOS_TRACE_LEVEL_INFO,
17069 FL("ioctl return cap tsf cmd, ret = %d"), ret);
17070 return ret;
17071}
17072
17073void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
17074{
17075
17076 if (adapter == NULL) {
17077 hddLog(VOS_TRACE_LEVEL_ERROR,
17078 FL("TSF init on a null adapter!"));
17079 return;
17080 }
17081
17082 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
17083 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17084 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
17085 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
17086 adapter->tsf_cap_ctx.tsf_high = 0;
17087 adapter->tsf_cap_ctx.tsf_low = 0;
17088}
17089
17090#endif
17091
Jeff Johnson295189b2012-06-20 16:38:30 -070017092//Register the module init/exit functions
17093module_init(hdd_module_init);
17094module_exit(hdd_module_exit);
17095
17096MODULE_LICENSE("Dual BSD/GPL");
17097MODULE_AUTHOR("Qualcomm Atheros, Inc.");
17098MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
17099
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070017100module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
17101 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070017102
Jeff Johnson76052702013-04-16 13:55:05 -070017103module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070017104 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080017105
17106module_param(enable_dfs_chan_scan, int,
17107 S_IRUSR | S_IRGRP | S_IROTH);
17108
17109module_param(enable_11d, int,
17110 S_IRUSR | S_IRGRP | S_IROTH);
17111
17112module_param(country_code, charp,
17113 S_IRUSR | S_IRGRP | S_IROTH);