blob: 5be89cc5c43e327268af5a8097a675e31b6a5757 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +05302 * Copyright (c) 2012-2016 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
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530216static vos_wake_lock_t wlan_wake_lock;
217
Jeff Johnson295189b2012-06-20 16:38:30 -0700218/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700219static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700220
221//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700222static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
223static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
224static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530225
226#ifdef WLAN_FEATURE_RMC
227static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
228
229static int hdd_open_cesium_nl_sock(void);
230static void hdd_close_cesium_nl_sock(void);
231static struct sock *cesium_nl_srv_sock;
232static v_U16_t cesium_pid;
233
234static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
235 tANI_U8 *tx_fail_count,
236 tANI_U16 *pid);
237
238static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
239
240#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700241void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800242void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700243
Jeff Johnson295189b2012-06-20 16:38:30 -0700244v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530245 struct sk_buff *skb
246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
247 , void *accel_priv
248#endif
249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
250 , select_queue_fallback_t fallback
251#endif
252);
Jeff Johnson295189b2012-06-20 16:38:30 -0700253
254#ifdef WLAN_FEATURE_PACKET_FILTERING
255static void hdd_set_multicast_list(struct net_device *dev);
256#endif
257
258void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
259
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800260#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800261void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
262static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700263static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
264 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
265 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700266static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
267 tANI_U8 *pTargetApBssid,
268 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530270
271/* Store WLAN driver info in a global variable such that crash debugger
272 can extract it from driver debug symbol and crashdump for post processing */
273tANI_U8 g_wlan_driver[ ] = "pronto_driver";
274
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800275#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700276VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800277#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700278
Mihir Shetee1093ba2014-01-21 20:13:32 +0530279static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530280const char * hdd_device_modetoString(v_U8_t device_mode)
281{
282 switch(device_mode)
283 {
284 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
285 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
286 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
287 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
288 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
289 CASE_RETURN_STRING( WLAN_HDD_FTM );
290 CASE_RETURN_STRING( WLAN_HDD_IBSS );
291 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
292 default:
293 return "device_mode Unknown";
294 }
295}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530296
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530297static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 unsigned long state,
299 void *ndev)
300{
301 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700303 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700304#ifdef WLAN_BTAMP_FEATURE
305 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700306#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530307 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700308
309 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700311 (strncmp(dev->name, "p2p", 3)))
312 return NOTIFY_DONE;
313
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700315 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700316
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800319 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 VOS_ASSERT(0);
321 return NOTIFY_DONE;
322 }
323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
325 if (NULL == pHddCtx)
326 {
327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
328 VOS_ASSERT(0);
329 return NOTIFY_DONE;
330 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800331 if (pHddCtx->isLogpInProgress)
332 return NOTIFY_DONE;
333
Jeff Johnson27cee452013-03-27 11:10:24 -0700334
335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
336 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700337
338 switch (state) {
339 case NETDEV_REGISTER:
340 break;
341
342 case NETDEV_UNREGISTER:
343 break;
344
345 case NETDEV_UP:
346 break;
347
348 case NETDEV_DOWN:
349 break;
350
351 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700352 if(TRUE == pAdapter->isLinkUpSvcNeeded)
353 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700354 break;
355
356 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530357 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530358 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530359 {
360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
361 "%s: Timeout occurred while waiting for abortscan %ld",
362 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 }
364 else
365 {
366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530367 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 }
369#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 status = WLANBAP_StopAmp();
372 if(VOS_STATUS_SUCCESS != status )
373 {
374 pHddCtx->isAmpAllowed = VOS_TRUE;
375 hddLog(VOS_TRACE_LEVEL_FATAL,
376 "%s: Failed to stop AMP", __func__);
377 }
378 else
379 {
380 //a state m/c implementation in PAL is TBD to avoid this delay
381 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700382 if ( pHddCtx->isAmpAllowed )
383 {
384 WLANBAP_DeregisterFromHCI();
385 pHddCtx->isAmpAllowed = VOS_FALSE;
386 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 }
388#endif //WLAN_BTAMP_FEATURE
389 break;
390
391 default:
392 break;
393 }
394
395 return NOTIFY_DONE;
396}
397
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530398static int hdd_netdev_notifier_call(struct notifier_block * nb,
399 unsigned long state,
400 void *ndev)
401{
402 int ret;
403 vos_ssr_protect(__func__);
404 ret = __hdd_netdev_notifier_call( nb, state, ndev);
405 vos_ssr_unprotect(__func__);
406 return ret;
407}
408
Jeff Johnson295189b2012-06-20 16:38:30 -0700409struct notifier_block hdd_netdev_notifier = {
410 .notifier_call = hdd_netdev_notifier_call,
411};
412
413/*---------------------------------------------------------------------------
414 * Function definitions
415 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700416void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
417void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700418//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700419static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700420#ifndef MODULE
421/* current con_mode - used only for statically linked driver
422 * con_mode is changed by userspace to indicate a mode change which will
423 * result in calling the module exit and init functions. The module
424 * exit function will clean up based on the value of con_mode prior to it
425 * being changed by userspace. So curr_con_mode records the current con_mode
426 * for exit when con_mode becomes the next mode for init
427 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700429#endif
430
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530431#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
432/**
433 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
434 * @hdd_ctx: hdd global context
435 *
436 * Return: none
437 */
438static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
439{
440 uint8_t i;
441
442 mutex_init(&hdd_ctx->op_ctx.op_lock);
443 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
444 {
445 hdd_ctx->op_ctx.op_table[i].request_id = 0;
446 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
447 }
448}
449#else
450static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
451{
452}
453#endif
454
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800455/**---------------------------------------------------------------------------
456
457 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
458
459 Called immediately after the cfg.ini is read in order to configure
460 the desired trace levels.
461
462 \param - moduleId - module whose trace level is being configured
463 \param - bitmask - bitmask of log levels to be enabled
464
465 \return - void
466
467 --------------------------------------------------------------------------*/
468static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
469{
470 wpt_tracelevel level;
471
472 /* if the bitmask is the default value, then a bitmask was not
473 specified in cfg.ini, so leave the logging level alone (it
474 will remain at the "compiled in" default value) */
475 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
476 {
477 return;
478 }
479
480 /* a mask was specified. start by disabling all logging */
481 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
482
483 /* now cycle through the bitmask until all "set" bits are serviced */
484 level = VOS_TRACE_LEVEL_FATAL;
485 while (0 != bitmask)
486 {
487 if (bitmask & 1)
488 {
489 vos_trace_setValue(moduleId, level, 1);
490 }
491 level++;
492 bitmask >>= 1;
493 }
494}
495
496
Jeff Johnson295189b2012-06-20 16:38:30 -0700497/**---------------------------------------------------------------------------
498
499 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
500
501 Called immediately after the cfg.ini is read in order to configure
502 the desired trace levels in the WDI.
503
504 \param - moduleId - module whose trace level is being configured
505 \param - bitmask - bitmask of log levels to be enabled
506
507 \return - void
508
509 --------------------------------------------------------------------------*/
510static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
511{
512 wpt_tracelevel level;
513
514 /* if the bitmask is the default value, then a bitmask was not
515 specified in cfg.ini, so leave the logging level alone (it
516 will remain at the "compiled in" default value) */
517 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
518 {
519 return;
520 }
521
522 /* a mask was specified. start by disabling all logging */
523 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
524
525 /* now cycle through the bitmask until all "set" bits are serviced */
526 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
527 while (0 != bitmask)
528 {
529 if (bitmask & 1)
530 {
531 wpalTraceSetLevel(moduleId, level, 1);
532 }
533 level++;
534 bitmask >>= 1;
535 }
536}
Jeff Johnson295189b2012-06-20 16:38:30 -0700537
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530538/*
539 * FUNCTION: wlan_hdd_validate_context
540 * This function is used to check the HDD context
541 */
542int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
543{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530544
545 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
546 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530548 "%s: HDD context is Null", __func__);
549 return -ENODEV;
550 }
551
552 if (pHddCtx->isLogpInProgress)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530555 "%s: LOGP %s. Ignore!!", __func__,
556 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
557 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530558 return -EAGAIN;
559 }
560
Mihir Shete18156292014-03-11 15:38:30 +0530561 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530564 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
565 return -EAGAIN;
566 }
567 return 0;
568}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700569#ifdef CONFIG_ENABLE_LINUX_REG
570void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
571{
572 hdd_adapter_t *pAdapter = NULL;
573 hdd_station_ctx_t *pHddStaCtx = NULL;
574 eCsrPhyMode phyMode;
575 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530576
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700577 if (NULL == pHddCtx)
578 {
579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
580 "HDD Context is null !!");
581 return ;
582 }
583
584 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
585 if (NULL == pAdapter)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "pAdapter is null !!");
589 return ;
590 }
591
592 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
593 if (NULL == pHddStaCtx)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "pHddStaCtx is null !!");
597 return ;
598 }
599
600 cfg_param = pHddCtx->cfg_ini;
601 if (NULL == cfg_param)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
604 "cfg_params not available !!");
605 return ;
606 }
607
608 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
609
610 if (!pHddCtx->isVHT80Allowed)
611 {
612 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
613 (eCSR_DOT11_MODE_11ac == phyMode) ||
614 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
617 "Setting phymode to 11n!!");
618 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
619 }
620 }
621 else
622 {
623 /*New country Supports 11ac as well resetting value back from .ini*/
624 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
625 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
626 return ;
627 }
628
629 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
630 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
631 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
632 {
633 VOS_STATUS vosStatus;
634
635 // need to issue a disconnect to CSR.
636 INIT_COMPLETION(pAdapter->disconnect_comp_var);
637 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
638 pAdapter->sessionId,
639 eCSR_DISCONNECT_REASON_UNSPECIFIED );
640
641 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530642 {
643 long ret;
644
645 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700646 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 if (0 >= ret)
648 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
649 ret);
650 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700651
652 }
653}
654#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530655void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
656{
657 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
658 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
659 hdd_config_t *cfg_param;
660 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530661 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662
663 if (NULL == pHddCtx)
664 {
665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
666 "HDD Context is null !!");
667 return ;
668 }
669
670 cfg_param = pHddCtx->cfg_ini;
671
672 if (NULL == cfg_param)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "cfg_params not available !!");
676 return ;
677 }
678
679 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
680
681 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
682 {
683 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
684 (eCSR_DOT11_MODE_11ac == phyMode) ||
685 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
686 {
687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
688 "Setting phymode to 11n!!");
689 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
690 }
691 }
692 else
693 {
694 /*New country Supports 11ac as well resetting value back from .ini*/
695 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
696 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
697 return ;
698 }
699
700 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
701 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
702 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
703 {
704 VOS_STATUS vosStatus;
705
706 // need to issue a disconnect to CSR.
707 INIT_COMPLETION(pAdapter->disconnect_comp_var);
708 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
709 pAdapter->sessionId,
710 eCSR_DISCONNECT_REASON_UNSPECIFIED );
711
712 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530713 {
714 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530715 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530716 if (ret <= 0)
717 {
718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
719 "wait on disconnect_comp_var is failed %ld", ret);
720 }
721 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722
723 }
724}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700725#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530726
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700727void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
728{
729 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
730 hdd_config_t *cfg_param;
731
732 if (NULL == pHddCtx)
733 {
734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
735 "HDD Context is null !!");
736 return ;
737 }
738
739 cfg_param = pHddCtx->cfg_ini;
740
741 if (NULL == cfg_param)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "cfg_params not available !!");
745 return ;
746 }
747
Agarwal Ashish738843c2014-09-25 12:27:56 +0530748 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
749 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700750 {
751 /*New country doesn't support DFS */
752 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
753 }
754 else
755 {
756 /*New country Supports DFS as well resetting value back from .ini*/
757 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
758 }
759
760}
761
Abhishek Singh00b71972016-01-07 10:51:04 +0530762#ifdef WLAN_FEATURE_RMC
763static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
764{
765 tANI_U8 *inPtr = pValue;
766 int tempInt;
767 int v = 0;
768 char buf[32];
769 *pRmcEnable = 0;
770
771 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
772 /*no argument after the command*/
773 if (NULL == inPtr)
774 {
775 return 0;
776 }
777
778 /*no space after the command*/
779 else if (SPACE_ASCII_VALUE != *inPtr)
780 {
781 return 0;
782 }
783
784 /*removing empty spaces*/
785 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
786
787 /*no argument followed by spaces*/
788 if ('\0' == *inPtr)
789 {
790 return 0;
791 }
792
793 /* getting the first argument which enables or disables RMC
794 * for input IP v4 address*/
795 sscanf(inPtr, "%32s ", buf);
796 v = kstrtos32(buf, 10, &tempInt);
797 if ( v < 0)
798 {
799 return -EINVAL;
800 }
801
802 *pRmcEnable = tempInt;
803
804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
805 "ucRmcEnable: %d", *pRmcEnable);
806
807 return 0;
808}
809
810/* Function header left blank Intentionally */
811static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
812 tANI_U32 *pActionPeriod)
813{
814 tANI_U8 *inPtr = pValue;
815 int tempInt;
816 int v = 0;
817 char buf[32];
818 *pActionPeriod = 0;
819
820 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
821 /*no argument after the command*/
822 if (NULL == inPtr)
823 {
824 return -EINVAL;
825 }
826
827 /*no space after the command*/
828 else if (SPACE_ASCII_VALUE != *inPtr)
829 {
830 return -EINVAL;
831 }
832
833 /*removing empty spaces*/
834 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
835
836 /*no argument followed by spaces*/
837 if ('\0' == *inPtr)
838 {
839 return 0;
840 }
841
842 /* getting the first argument which enables or disables RMC
843 * for input IP v4 address*/
844 sscanf(inPtr, "%32s ", buf);
845 v = kstrtos32(buf, 10, &tempInt);
846 if ( v < 0)
847 {
848 return -EINVAL;
849 }
850
851 /* Range checking for passed paramter */
852 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
853 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
854 {
855 return -EINVAL;
856 }
857
858 *pActionPeriod = tempInt;
859
860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
861 "uActionPeriod: %d", *pActionPeriod);
862
863 return 0;
864}
865
866/* Function header left blank Intentionally */
867static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
868 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
869{
870 tANI_U8 *inPtr = pValue;
871 int tempInt;
872 int v = 0;
873 char buf[32];
874 *pRate = 0;
875 *pTxFlags = 0;
876
877 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
878 /*no argument after the command*/
879 if (NULL == inPtr)
880 {
881 return -EINVAL;
882 }
883
884 /*no space after the command*/
885 else if (SPACE_ASCII_VALUE != *inPtr)
886 {
887 return -EINVAL;
888 }
889
890 /*removing empty spaces*/
891 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
892
893 /*no argument followed by spaces*/
894 if ('\0' == *inPtr)
895 {
896 return 0;
897 }
898
899 /*
900 * getting the first argument which sets multicast rate.
901 */
902 sscanf(inPtr, "%32s ", buf);
903 v = kstrtos32(buf, 10, &tempInt);
904 if ( v < 0)
905 {
906 return -EINVAL;
907 }
908
909 /*
910 * Validate the multicast rate.
911 */
912 switch (tempInt)
913 {
914 default:
915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
916 "Unsupported rate: %d", tempInt);
917 return -EINVAL;
918 case 0:
919 case 6:
920 case 9:
921 case 12:
922 case 18:
923 case 24:
924 case 36:
925 case 48:
926 case 54:
927 *pTxFlags = eHAL_TX_RATE_LEGACY;
928 *pRate = tempInt * 10;
929 break;
930 case 65:
931 *pTxFlags = eHAL_TX_RATE_HT20;
932 *pRate = tempInt * 10;
933 break;
934 case 72:
935 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
936 *pRate = 722; /* fractional rate 72.2 Mbps */
937 break;
938 }
939
940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
941 "Rate: %d", *pRate);
942
943 return 0;
944}
945
946/**---------------------------------------------------------------------------
947
948 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
949 Peer Info request
950
951 This is an asynchronous callback function from SME when the peer info
952 is received
953
954 \pUserData -> Adapter private data
955 \pPeerInfoRsp -> Peer info response
956
957 \return - 0 for success non-zero for failure
958 --------------------------------------------------------------------------*/
959static void
960hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
961{
962 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
963 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
964 hdd_station_ctx_t *pStaCtx;
965 v_U8_t i;
966
967 /*Sanity check*/
968 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
969 {
970 hddLog(LOGE,
971 FL("invalid adapter or adapter has invalid magic"));
972 return;
973 }
974
975 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 if (NULL != pStaCtx && NULL != pPeerInfo &&
977 eHAL_STATUS_SUCCESS == pPeerInfo->status)
978 {
979 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
980 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
981
982 /* Paranoia check */
983 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
984 {
985 for (i = 0; i < pPeerInfo->numPeers; i++)
986 {
987 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
988 &pPeerInfo->peerInfoParams[i],
989 sizeof(hdd_ibss_peer_info_params_t));
990 }
991 hddLog(LOG1,
992 FL("Peer Info copied in HDD"));
993 }
994 else
995 {
996 hddLog(LOGE,
997 FL(" Number of peers %d returned is more than limit %d"),
998 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
999 }
1000 }
1001 else
1002 {
1003 hddLog(LOG1,
1004 FL("peerInfo returned is NULL"));
1005 }
1006
1007 complete(&pAdapter->ibss_peer_info_comp);
1008}
1009
1010/**---------------------------------------------------------------------------
1011
1012 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1013
1014 Request function to get IBSS peer info from lower layers
1015
1016 \pAdapter -> Adapter context
1017
1018 \return - 0 for success non-zero for failure
1019 --------------------------------------------------------------------------*/
1020static
1021VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1022{
1023 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1024 long status;
1025 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1026
1027 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1028
1029 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1030 hdd_cfg80211_get_ibss_peer_info_cb,
1031 VOS_TRUE, 0xFF);
1032
1033 if (VOS_STATUS_SUCCESS == retStatus)
1034 {
1035 status = wait_for_completion_interruptible_timeout
1036 (&pAdapter->ibss_peer_info_comp,
1037 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1038
1039 /* status will be 0 if timed out */
1040 if (status <= 0)
1041 {
1042 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1043 __func__, status);
1044 retStatus = VOS_STATUS_E_FAILURE;
1045 return retStatus;
1046 }
1047 }
1048 else
1049 {
1050 hddLog(VOS_TRACE_LEVEL_WARN,
1051 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1052 }
1053
1054 return retStatus;
1055}
1056
1057/**---------------------------------------------------------------------------
1058
1059 \brief hdd_cfg80211_get_ibss_peer_info() -
1060
1061 Request function to get IBSS peer info from lower layers
1062
1063 \pAdapter -> Adapter context
1064 \staIdx -> Sta index for which the peer info is requested
1065
1066 \return - 0 for success non-zero for failure
1067 --------------------------------------------------------------------------*/
1068static VOS_STATUS
1069hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1070{
1071 long status;
1072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1073 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1074
1075 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1076
1077 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1078 hdd_cfg80211_get_ibss_peer_info_cb,
1079 VOS_FALSE, staIdx);
1080
1081 if (VOS_STATUS_SUCCESS == retStatus)
1082 {
1083 status = wait_for_completion_interruptible_timeout
1084 (&pAdapter->ibss_peer_info_comp,
1085 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1086
1087 /* status = 0 on timeout */
1088 if (status <= 0)
1089 {
1090 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1091 __func__, status);
1092 retStatus = VOS_STATUS_E_FAILURE;
1093 return retStatus;
1094 }
1095 }
1096 else
1097 {
1098 hddLog(VOS_TRACE_LEVEL_WARN,
1099 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1100 }
1101
1102 return retStatus;
1103}
1104
1105/* Function header left blank Intentionally */
1106VOS_STATUS
1107hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1108{
1109 tANI_U8 *inPtr = pValue;
1110 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1111
1112 /*no argument after the command*/
1113 if (NULL == inPtr)
1114 {
1115 return VOS_STATUS_E_FAILURE;;
1116 }
1117
1118 /*no space after the command*/
1119 else if (SPACE_ASCII_VALUE != *inPtr)
1120 {
1121 return VOS_STATUS_E_FAILURE;;
1122 }
1123
1124 /*removing empty spaces*/
1125 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1126
1127 /*no argument followed by spaces*/
1128 if ('\0' == *inPtr)
1129 {
1130 return VOS_STATUS_E_FAILURE;;
1131 }
1132
1133 /*getting the first argument ie the peer mac address */
1134 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1135 inPtr[11] != ':' || inPtr[14] != ':')
1136 {
1137 return VOS_STATUS_E_FAILURE;;
1138 }
1139 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1140 (unsigned int *)&pPeerMacAddr->bytes[0],
1141 (unsigned int *)&pPeerMacAddr->bytes[1],
1142 (unsigned int *)&pPeerMacAddr->bytes[2],
1143 (unsigned int *)&pPeerMacAddr->bytes[3],
1144 (unsigned int *)&pPeerMacAddr->bytes[4],
1145 (unsigned int *)&pPeerMacAddr->bytes[5]);
1146
1147 /* The command buffer seems to be fine */
1148 return VOS_STATUS_SUCCESS;
1149}
1150
1151/* Function header left blank Intentionally */
1152static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1153 tANI_U32 limit)
1154{
1155 tANI_U8 len;
1156 tANI_U8 data;
1157
1158 /* skip white space */
1159 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1160 {
1161 command++;
1162 limit--;
1163 }
1164
1165 /* skip element id and element length */
1166 len = 2;
1167
1168 /* extract oui */
1169 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1170 (limit > 1))
1171 {
1172 /* Convert ASCII to decimal */
1173 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1174 ie[len++] = data;
1175 command += 2;
1176 limit -= 2;
1177 }
1178
1179 /* skip white space */
1180 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1181 {
1182 command++;
1183 limit--;
1184 }
1185
1186 /* extract data */
1187 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1188 (limit > 1))
1189 {
1190 /* Convert ASCII to decimal */
1191 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1192 ie[len++] = data;
1193 command += 2;
1194 limit -= 2;
1195 }
1196
1197 /* fill element id and element length */
1198 ie[0] = IE_EID_VENDOR;
1199 ie[1] = len - 2;
1200
1201 return len;
1202}
1203
1204static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1205{
1206 tANI_U32 ieLenPresent = 0;
1207 int left = addIeLen;
1208 v_U8_t *ptr = addIePtr;
1209 v_U8_t elem_id,elem_len;
1210
1211 while(left >= 2)
1212 {
1213 elem_id = ptr[0];
1214 elem_len = ptr[1];
1215 left -= 2;
1216 if(elem_len > left)
1217 {
1218 hddLog(LOGE,
1219 FL("****Invalid elem_len=%d left=%d*****"),
1220 elem_len,left);
1221 return 0;
1222 }
1223 if ((elem_id == IE_EID_VENDOR) &&
1224 (left >= WPA_OUI_TYPE_SIZE))
1225 {
1226 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1227 WPA_OUI_TYPE_SIZE))
1228 {
1229 ieLenPresent += elem_len + 2;
1230 return ieLenPresent;
1231 }
1232 }
1233 ieLenPresent += (elem_len + 2);
1234 left -= elem_len;
1235 ptr += (elem_len + 2);
1236 }
1237 return 0;
1238}
1239
1240#endif /* WLAN_FEATURE_RMC */
1241
Rajeev79dbe4c2013-10-05 11:03:42 +05301242#ifdef FEATURE_WLAN_BATCH_SCAN
1243
1244/**---------------------------------------------------------------------------
1245
1246 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1247 input string
1248
1249 This function extracts assigned integer from string in below format:
1250 "STRING=10" : extracts integer 10 from this string
1251
1252 \param - pInPtr Pointer to input string
1253 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1254 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1255 assigned
1256 \param - pLastArg to tell whether it is last arguement in input string or
1257 not
1258
1259 \return - NULL for failure cases
1260 pointer to next arguement in input string for success cases
1261 --------------------------------------------------------------------------*/
1262static tANI_U8 *
1263hdd_extract_assigned_int_from_str
1264(
1265 tANI_U8 *pInPtr,
1266 tANI_U8 base,
1267 tANI_U32 *pOutPtr,
1268 tANI_U8 *pLastArg
1269)
1270{
1271 int tempInt;
1272 int v = 0;
1273 char buf[32];
1274 int val = 0;
1275 *pLastArg = FALSE;
1276
1277 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1278 if (NULL == pInPtr)
1279 {
1280 return NULL;
1281 }
1282
1283 pInPtr++;
1284
1285 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1286
1287 val = sscanf(pInPtr, "%32s ", buf);
1288 if (val < 0 && val > strlen(pInPtr))
1289 {
1290 return NULL;
1291 }
1292 pInPtr += val;
1293 v = kstrtos32(buf, base, &tempInt);
1294 if (v < 0)
1295 {
1296 return NULL;
1297 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001298 if (tempInt < 0)
1299 {
1300 tempInt = 0;
1301 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301302 *pOutPtr = tempInt;
1303
1304 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1305 if (NULL == pInPtr)
1306 {
1307 *pLastArg = TRUE;
1308 return NULL;
1309 }
1310 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1311
1312 return pInPtr;
1313}
1314
1315/**---------------------------------------------------------------------------
1316
1317 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1318 input string
1319
1320 This function extracts assigned character from string in below format:
1321 "STRING=A" : extracts char 'A' from this string
1322
1323 \param - pInPtr Pointer to input string
1324 \param - pOutPtr Pointer to variable in which extracted char needs to be
1325 assigned
1326 \param - pLastArg to tell whether it is last arguement in input string or
1327 not
1328
1329 \return - NULL for failure cases
1330 pointer to next arguement in input string for success cases
1331 --------------------------------------------------------------------------*/
1332static tANI_U8 *
1333hdd_extract_assigned_char_from_str
1334(
1335 tANI_U8 *pInPtr,
1336 tANI_U8 *pOutPtr,
1337 tANI_U8 *pLastArg
1338)
1339{
1340 *pLastArg = FALSE;
1341
1342 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1343 if (NULL == pInPtr)
1344 {
1345 return NULL;
1346 }
1347
1348 pInPtr++;
1349
1350 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1351
1352 *pOutPtr = *pInPtr;
1353
1354 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1355 if (NULL == pInPtr)
1356 {
1357 *pLastArg = TRUE;
1358 return NULL;
1359 }
1360 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1361
1362 return pInPtr;
1363}
1364
1365
1366/**---------------------------------------------------------------------------
1367
1368 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1369
1370 This function parses set batch scan command in below format:
1371 WLS_BATCHING_SET <space> followed by below arguements
1372 "SCANFREQ=XX" : Optional defaults to 30 sec
1373 "MSCAN=XX" : Required number of scans to attempt to batch
1374 "BESTN=XX" : Best Network (RSSI) defaults to 16
1375 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1376 A. implies only 5 GHz , B. implies only 2.4GHz
1377 "RTT=X" : optional defaults to 0
1378 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1379 error
1380
1381 For example input commands:
1382 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1383 translated into set batch scan with following parameters:
1384 a) Frequence 60 seconds
1385 b) Batch 10 scans together
1386 c) Best RSSI to be 20
1387 d) 5GHz band only
1388 e) RTT is equal to 0
1389
1390 \param - pValue Pointer to input channel list
1391 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1392
1393 \return - 0 for success non-zero for failure
1394
1395 --------------------------------------------------------------------------*/
1396static int
1397hdd_parse_set_batchscan_command
1398(
1399 tANI_U8 *pValue,
1400 tSirSetBatchScanReq *pHddSetBatchScanReq
1401)
1402{
1403 tANI_U8 *inPtr = pValue;
1404 tANI_U8 val = 0;
1405 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301406 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001407 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301408 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1409 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1410 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001411 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301412
Rajeev79dbe4c2013-10-05 11:03:42 +05301413 /*go to space after WLS_BATCHING_SET command*/
1414 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1415 /*no argument after the command*/
1416 if (NULL == inPtr)
1417 {
1418 return -EINVAL;
1419 }
1420
1421 /*no space after the command*/
1422 else if (SPACE_ASCII_VALUE != *inPtr)
1423 {
1424 return -EINVAL;
1425 }
1426
1427 /*removing empty spaces*/
1428 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1429
1430 /*no argument followed by spaces*/
1431 if ('\0' == *inPtr)
1432 {
1433 return -EINVAL;
1434 }
1435
1436 /*check and parse SCANFREQ*/
1437 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1438 {
1439 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001441
Rajeev Kumarc933d982013-11-18 20:04:20 -08001442 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001443 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001445 }
1446
Rajeev79dbe4c2013-10-05 11:03:42 +05301447 if ( (NULL == inPtr) || (TRUE == lastArg))
1448 {
1449 return -EINVAL;
1450 }
1451 }
1452
1453 /*check and parse MSCAN*/
1454 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1455 {
1456 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001457 &nMscan, &lastArg);
1458
1459 if (0 == nMscan)
1460 {
1461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1462 "invalid MSCAN=%d", nMscan);
1463 return -EINVAL;
1464 }
1465
Rajeev79dbe4c2013-10-05 11:03:42 +05301466 if (TRUE == lastArg)
1467 {
1468 goto done;
1469 }
1470 else if (NULL == inPtr)
1471 {
1472 return -EINVAL;
1473 }
1474 }
1475 else
1476 {
1477 return -EINVAL;
1478 }
1479
1480 /*check and parse BESTN*/
1481 if ((strncmp(inPtr, "BESTN", 5) == 0))
1482 {
1483 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001484 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001485
Rajeev Kumarc933d982013-11-18 20:04:20 -08001486 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001487 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001488 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001489 }
1490
Rajeev79dbe4c2013-10-05 11:03:42 +05301491 if (TRUE == lastArg)
1492 {
1493 goto done;
1494 }
1495 else if (NULL == inPtr)
1496 {
1497 return -EINVAL;
1498 }
1499 }
1500
1501 /*check and parse CHANNEL*/
1502 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1503 {
1504 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001505
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 if (('A' == val) || ('a' == val))
1507 {
c_hpothuebf89732014-02-25 13:00:24 +05301508 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301509 }
1510 else if (('B' == val) || ('b' == val))
1511 {
c_hpothuebf89732014-02-25 13:00:24 +05301512 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 }
1514 else
1515 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001516 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1517 }
1518
1519 if (TRUE == lastArg)
1520 {
1521 goto done;
1522 }
1523 else if (NULL == inPtr)
1524 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301525 return -EINVAL;
1526 }
1527 }
1528
1529 /*check and parse RTT*/
1530 if ((strncmp(inPtr, "RTT", 3) == 0))
1531 {
1532 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001533 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301534 if (TRUE == lastArg)
1535 {
1536 goto done;
1537 }
1538 if (NULL == inPtr)
1539 {
1540 return -EINVAL;
1541 }
1542 }
1543
1544
1545done:
1546
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001547 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1548 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1549 pHddSetBatchScanReq->bestNetwork = nBestN;
1550 pHddSetBatchScanReq->rfBand = ucRfBand;
1551 pHddSetBatchScanReq->rtt = nRtt;
1552
Rajeev79dbe4c2013-10-05 11:03:42 +05301553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1554 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1555 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1556 pHddSetBatchScanReq->scanFrequency,
1557 pHddSetBatchScanReq->numberOfScansToBatch,
1558 pHddSetBatchScanReq->bestNetwork,
1559 pHddSetBatchScanReq->rfBand,
1560 pHddSetBatchScanReq->rtt);
1561
1562 return 0;
1563}/*End of hdd_parse_set_batchscan_command*/
1564
1565/**---------------------------------------------------------------------------
1566
1567 \brief hdd_set_batch_scan_req_callback () - This function is called after
1568 receiving set batch scan response from FW and it saves set batch scan
1569 response data FW to HDD context and sets the completion event on
1570 which hdd_ioctl is waiting
1571
1572 \param - callbackContext Pointer to HDD adapter
1573 \param - pRsp Pointer to set batch scan response data received from FW
1574
1575 \return - nothing
1576
1577 --------------------------------------------------------------------------*/
1578static void hdd_set_batch_scan_req_callback
1579(
1580 void *callbackContext,
1581 tSirSetBatchScanRsp *pRsp
1582)
1583{
1584 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1585 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1586
1587 /*sanity check*/
1588 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1589 {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1591 "%s: Invalid pAdapter magic", __func__);
1592 VOS_ASSERT(0);
1593 return;
1594 }
1595 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1596
1597 /*save set batch scan response*/
1598 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1599
1600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1601 "Received set batch scan rsp from FW with nScansToBatch=%d",
1602 pHddSetBatchScanRsp->nScansToBatch);
1603
1604 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1605 complete(&pAdapter->hdd_set_batch_scan_req_var);
1606
1607 return;
1608}/*End of hdd_set_batch_scan_req_callback*/
1609
1610
1611/**---------------------------------------------------------------------------
1612
1613 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1614 info in hdd batch scan response queue
1615
1616 \param - pAdapter Pointer to hdd adapter
1617 \param - pAPMetaInfo Pointer to access point meta info
1618 \param - scanId scan ID of batch scan response
1619 \param - isLastAp tells whether AP is last AP in batch scan response or not
1620
1621 \return - nothing
1622
1623 --------------------------------------------------------------------------*/
1624static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1625 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1626{
1627 tHddBatchScanRsp *pHead;
1628 tHddBatchScanRsp *pNode;
1629 tHddBatchScanRsp *pPrev;
1630 tHddBatchScanRsp *pTemp;
1631 tANI_U8 ssidLen;
1632
1633 /*head of hdd batch scan response queue*/
1634 pHead = pAdapter->pBatchScanRsp;
1635
1636 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1637 if (NULL == pNode)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: Could not allocate memory", __func__);
1641 VOS_ASSERT(0);
1642 return;
1643 }
1644
1645 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1646 sizeof(pNode->ApInfo.bssid));
1647 ssidLen = strlen(pApMetaInfo->ssid);
1648 if (SIR_MAX_SSID_SIZE < ssidLen)
1649 {
1650 /*invalid scan result*/
1651 vos_mem_free(pNode);
1652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1654 return;
1655 }
1656 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1657 /*null terminate ssid*/
1658 pNode->ApInfo.ssid[ssidLen] = '\0';
1659 pNode->ApInfo.ch = pApMetaInfo->ch;
1660 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1661 pNode->ApInfo.age = pApMetaInfo->timestamp;
1662 pNode->ApInfo.batchId = scanId;
1663 pNode->ApInfo.isLastAp = isLastAp;
1664
1665 pNode->pNext = NULL;
1666 if (NULL == pHead)
1667 {
1668 pAdapter->pBatchScanRsp = pNode;
1669 }
1670 else
1671 {
1672 pTemp = pHead;
1673 while (NULL != pTemp)
1674 {
1675 pPrev = pTemp;
1676 pTemp = pTemp->pNext;
1677 }
1678 pPrev->pNext = pNode;
1679 }
1680
1681 return;
1682}/*End of hdd_populate_batch_scan_rsp_queue*/
1683
1684/**---------------------------------------------------------------------------
1685
1686 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1687 receiving batch scan response indication from FW. It saves get batch scan
1688 response data in HDD batch scan response queue. This callback sets the
1689 completion event on which hdd_ioctl is waiting only after getting complete
1690 batch scan response data from FW
1691
1692 \param - callbackContext Pointer to HDD adapter
1693 \param - pRsp Pointer to get batch scan response data received from FW
1694
1695 \return - nothing
1696
1697 --------------------------------------------------------------------------*/
1698static void hdd_batch_scan_result_ind_callback
1699(
1700 void *callbackContext,
1701 void *pRsp
1702)
1703{
1704 v_BOOL_t isLastAp;
1705 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001706 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301707 tANI_U32 numberScanList;
1708 tANI_U32 nextScanListOffset;
1709 tANI_U32 nextApMetaInfoOffset;
1710 hdd_adapter_t* pAdapter;
1711 tpSirBatchScanList pScanList;
1712 tpSirBatchScanNetworkInfo pApMetaInfo;
1713 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1714 tSirSetBatchScanReq *pReq;
1715
1716 pAdapter = (hdd_adapter_t *)callbackContext;
1717 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001718 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301719 {
1720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: Invalid pAdapter magic", __func__);
1722 VOS_ASSERT(0);
1723 return;
1724 }
1725
1726 /*initialize locals*/
1727 pReq = &pAdapter->hddSetBatchScanReq;
1728 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1729 isLastAp = FALSE;
1730 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001731 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301732 numberScanList = 0;
1733 nextScanListOffset = 0;
1734 nextApMetaInfoOffset = 0;
1735 pScanList = NULL;
1736 pApMetaInfo = NULL;
1737
1738 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1739 {
1740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1741 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1742 isLastAp = TRUE;
1743 goto done;
1744 }
1745
1746 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "Batch scan rsp: numberScalList %d", numberScanList);
1749
1750 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1751 {
1752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1753 "%s: numberScanList %d", __func__, numberScanList);
1754 isLastAp = TRUE;
1755 goto done;
1756 }
1757
1758 while (numberScanList)
1759 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001760 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301761 nextScanListOffset);
1762 if (NULL == pScanList)
1763 {
1764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1765 "%s: pScanList is %p", __func__, pScanList);
1766 isLastAp = TRUE;
1767 goto done;
1768 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001769 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001771 "Batch scan rsp: numApMetaInfo %d scanId %d",
1772 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301773
1774 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1775 {
1776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1777 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1778 isLastAp = TRUE;
1779 goto done;
1780 }
1781
Rajeev Kumarce651e42013-10-21 18:57:15 -07001782 /*Initialize next AP meta info offset for next scan list*/
1783 nextApMetaInfoOffset = 0;
1784
Rajeev79dbe4c2013-10-05 11:03:42 +05301785 while (numApMetaInfo)
1786 {
1787 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1788 nextApMetaInfoOffset);
1789 if (NULL == pApMetaInfo)
1790 {
1791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1793 isLastAp = TRUE;
1794 goto done;
1795 }
1796 /*calculate AP age*/
1797 pApMetaInfo->timestamp =
1798 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1799
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001801 "%s: bssId "MAC_ADDRESS_STR
1802 " ch %d rssi %d timestamp %d", __func__,
1803 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1804 pApMetaInfo->ch, pApMetaInfo->rssi,
1805 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301806
1807 /*mark last AP in batch scan response*/
1808 if ((TRUE == pBatchScanRsp->isLastResult) &&
1809 (1 == numberScanList) && (1 == numApMetaInfo))
1810 {
1811 isLastAp = TRUE;
1812 }
1813
1814 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1815 /*store batch scan repsonse in hdd queue*/
1816 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1817 pScanList->scanId, isLastAp);
1818 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1819
1820 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1821 numApMetaInfo--;
1822 }
1823
Rajeev Kumarce651e42013-10-21 18:57:15 -07001824 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1825 + (sizeof(tSirBatchScanNetworkInfo)
1826 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301827 numberScanList--;
1828 }
1829
1830done:
1831
1832 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1833 requested from hdd_ioctl*/
1834 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1835 (TRUE == isLastAp))
1836 {
1837 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1838 complete(&pAdapter->hdd_get_batch_scan_req_var);
1839 }
1840
1841 return;
1842}/*End of hdd_batch_scan_result_ind_callback*/
1843
1844/**---------------------------------------------------------------------------
1845
1846 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1847 response as per batch scan FR request format by putting proper markers
1848
1849 \param - pDest pointer to destination buffer
1850 \param - cur_len current length
1851 \param - tot_len total remaining size which can be written to user space
1852 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1853 \param - pAdapter Pointer to HDD adapter
1854
1855 \return - ret no of characters written
1856
1857 --------------------------------------------------------------------------*/
1858static tANI_U32
1859hdd_format_batch_scan_rsp
1860(
1861 tANI_U8 *pDest,
1862 tANI_U32 cur_len,
1863 tANI_U32 tot_len,
1864 tHddBatchScanRsp *pApMetaInfo,
1865 hdd_adapter_t* pAdapter
1866)
1867{
1868 tANI_U32 ret = 0;
1869 tANI_U32 rem_len = 0;
1870 tANI_U8 temp_len = 0;
1871 tANI_U8 temp_total_len = 0;
1872 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1873 tANI_U8 *pTemp = temp;
1874
1875 /*Batch scan reponse needs to be returned to user space in
1876 following format:
1877 "scancount=X\n" where X is the number of scans in current batch
1878 batch
1879 "trunc\n" optional present if current scan truncated
1880 "bssid=XX:XX:XX:XX:XX:XX\n"
1881 "ssid=XXXX\n"
1882 "freq=X\n" frequency in Mhz
1883 "level=XX\n"
1884 "age=X\n" ms
1885 "dist=X\n" cm (-1 if not available)
1886 "errror=X\n" (-1if not available)
1887 "====\n" (end of ap marker)
1888 "####\n" (end of scan marker)
1889 "----\n" (end of results)*/
1890 /*send scan result in above format to user space based on
1891 available length*/
1892 /*The GET response may have more data than the driver can return in its
1893 buffer. In that case the buffer should be filled to the nearest complete
1894 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1895 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1896 The final buffer should end with "----\n"*/
1897
1898 /*sanity*/
1899 if (cur_len > tot_len)
1900 {
1901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1902 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1903 return 0;
1904 }
1905 else
1906 {
1907 rem_len = (tot_len - cur_len);
1908 }
1909
1910 /*end scan marker*/
1911 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1912 {
1913 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1914 pTemp += temp_len;
1915 temp_total_len += temp_len;
1916 }
1917
1918 /*bssid*/
1919 temp_len = snprintf(pTemp, sizeof(temp),
1920 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1921 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1922 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1923 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1924 pTemp += temp_len;
1925 temp_total_len += temp_len;
1926
1927 /*ssid*/
1928 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1929 pApMetaInfo->ApInfo.ssid);
1930 pTemp += temp_len;
1931 temp_total_len += temp_len;
1932
1933 /*freq*/
1934 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001935 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301936 pTemp += temp_len;
1937 temp_total_len += temp_len;
1938
1939 /*level*/
1940 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1941 pApMetaInfo->ApInfo.rssi);
1942 pTemp += temp_len;
1943 temp_total_len += temp_len;
1944
1945 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001946 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301947 pApMetaInfo->ApInfo.age);
1948 pTemp += temp_len;
1949 temp_total_len += temp_len;
1950
1951 /*dist*/
1952 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1953 pTemp += temp_len;
1954 temp_total_len += temp_len;
1955
1956 /*error*/
1957 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1958 pTemp += temp_len;
1959 temp_total_len += temp_len;
1960
1961 /*end AP marker*/
1962 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1963 pTemp += temp_len;
1964 temp_total_len += temp_len;
1965
1966 /*last AP in batch scan response*/
1967 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1968 {
1969 /*end scan marker*/
1970 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1971 pTemp += temp_len;
1972 temp_total_len += temp_len;
1973
1974 /*end batch scan result marker*/
1975 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1976 pTemp += temp_len;
1977 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001978
Rajeev79dbe4c2013-10-05 11:03:42 +05301979 }
1980
1981 if (temp_total_len < rem_len)
1982 {
1983 ret = temp_total_len + 1;
1984 strlcpy(pDest, temp, ret);
1985 pAdapter->isTruncated = FALSE;
1986 }
1987 else
1988 {
1989 pAdapter->isTruncated = TRUE;
1990 if (rem_len >= strlen("%%%%"))
1991 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001992 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301993 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001994 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301995 {
1996 ret = 0;
1997 }
1998 }
1999
2000 return ret;
2001
2002}/*End of hdd_format_batch_scan_rsp*/
2003
2004/**---------------------------------------------------------------------------
2005
2006 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2007 buffer starting with head of hdd batch scan response queue
2008
2009 \param - pAdapter Pointer to HDD adapter
2010 \param - pDest Pointer to user data buffer
2011 \param - cur_len current offset in user buffer
2012 \param - rem_len remaining no of bytes in user buffer
2013
2014 \return - number of bytes written in user buffer
2015
2016 --------------------------------------------------------------------------*/
2017
2018tANI_U32 hdd_populate_user_batch_scan_rsp
2019(
2020 hdd_adapter_t* pAdapter,
2021 tANI_U8 *pDest,
2022 tANI_U32 cur_len,
2023 tANI_U32 rem_len
2024)
2025{
2026 tHddBatchScanRsp *pHead;
2027 tHddBatchScanRsp *pPrev;
2028 tANI_U32 len;
2029
Rajeev79dbe4c2013-10-05 11:03:42 +05302030 pAdapter->isTruncated = FALSE;
2031
2032 /*head of hdd batch scan response queue*/
2033 pHead = pAdapter->pBatchScanRsp;
2034 while (pHead)
2035 {
2036 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2037 pAdapter);
2038 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002039 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302040 cur_len += len;
2041 if(TRUE == pAdapter->isTruncated)
2042 {
2043 /*result is truncated return rest of scan rsp in next req*/
2044 cur_len = rem_len;
2045 break;
2046 }
2047 pPrev = pHead;
2048 pHead = pHead->pNext;
2049 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002050 if (TRUE == pPrev->ApInfo.isLastAp)
2051 {
2052 pAdapter->prev_batch_id = 0;
2053 }
2054 else
2055 {
2056 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2057 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302058 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002059 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302060 }
2061
2062 return cur_len;
2063}/*End of hdd_populate_user_batch_scan_rsp*/
2064
2065/**---------------------------------------------------------------------------
2066
2067 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2068 scan response data from HDD queue to user space
2069 It does following in detail:
2070 a) if HDD has enough data in its queue then it 1st copies data to user
2071 space and then send get batch scan indication message to FW. In this
2072 case it does not wait on any event and batch scan response data will
2073 be populated in HDD response queue in MC thread context after receiving
2074 indication from FW
2075 b) else send get batch scan indication message to FW and wait on an event
2076 which will be set once HDD receives complete batch scan response from
2077 FW and then this function returns batch scan response to user space
2078
2079 \param - pAdapter Pointer to HDD adapter
2080 \param - pPrivData Pointer to priv_data
2081
2082 \return - 0 for success -EFAULT for failure
2083
2084 --------------------------------------------------------------------------*/
2085
2086int hdd_return_batch_scan_rsp_to_user
2087(
2088 hdd_adapter_t* pAdapter,
2089 hdd_priv_data_t *pPrivData,
2090 tANI_U8 *command
2091)
2092{
2093 tANI_U8 *pDest;
2094 tANI_U32 count = 0;
2095 tANI_U32 len = 0;
2096 tANI_U32 cur_len = 0;
2097 tANI_U32 rem_len = 0;
2098 eHalStatus halStatus;
2099 unsigned long rc;
2100 tSirTriggerBatchScanResultInd *pReq;
2101
2102 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2103 pReq->param = 0;/*batch scan client*/
2104 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2105 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2106
2107 cur_len = pPrivData->used_len;
2108 if (pPrivData->total_len > pPrivData->used_len)
2109 {
2110 rem_len = pPrivData->total_len - pPrivData->used_len;
2111 }
2112 else
2113 {
2114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2115 "%s: Invalid user data buffer total_len %d used_len %d",
2116 __func__, pPrivData->total_len, pPrivData->used_len);
2117 return -EFAULT;
2118 }
2119
2120 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2121 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2122 cur_len, rem_len);
2123 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2124
2125 /*enough scan result available in cache to return to user space or
2126 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002127 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302128 {
2129 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2130 halStatus = sme_TriggerBatchScanResultInd(
2131 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2132 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2133 pAdapter);
2134 if ( eHAL_STATUS_SUCCESS == halStatus )
2135 {
2136 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2137 {
2138 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2139 rc = wait_for_completion_timeout(
2140 &pAdapter->hdd_get_batch_scan_req_var,
2141 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302142 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302143 {
2144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302145 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2146 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302147 return -EFAULT;
2148 }
2149 }
2150
2151 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002152 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302153 pDest += len;
2154 cur_len += len;
2155
2156 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2157 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2158 cur_len, rem_len);
2159 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2160
2161 count = 0;
2162 len = (len - pPrivData->used_len);
2163 pDest = (command + pPrivData->used_len);
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002165 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302166 while(count < len)
2167 {
2168 printk("%c", *(pDest + count));
2169 count++;
2170 }
2171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2172 "%s: copy %d data to user buffer", __func__, len);
2173 if (copy_to_user(pPrivData->buf, pDest, len))
2174 {
2175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s: failed to copy data to user buffer", __func__);
2177 return -EFAULT;
2178 }
2179 }
2180 else
2181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2183 "sme_GetBatchScanScan returned failure halStatus %d",
2184 halStatus);
2185 return -EINVAL;
2186 }
2187 }
2188 else
2189 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302190 count = 0;
2191 len = (len - pPrivData->used_len);
2192 pDest = (command + pPrivData->used_len);
2193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002194 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302195 while(count < len)
2196 {
2197 printk("%c", *(pDest + count));
2198 count++;
2199 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2201 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 if (copy_to_user(pPrivData->buf, pDest, len))
2203 {
2204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2205 "%s: failed to copy data to user buffer", __func__);
2206 return -EFAULT;
2207 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302208 }
2209
2210 return 0;
2211} /*End of hdd_return_batch_scan_rsp_to_user*/
2212
Rajeev Kumar8b373292014-01-08 20:36:55 -08002213/**---------------------------------------------------------------------------
2214
2215 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2216 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2217 WLS_BATCHING VERSION
2218 WLS_BATCHING SET
2219 WLS_BATCHING GET
2220 WLS_BATCHING STOP
2221
2222 \param - pAdapter Pointer to HDD adapter
2223 \param - pPrivdata Pointer to priv_data
2224 \param - command Pointer to command
2225
2226 \return - 0 for success -EFAULT for failure
2227
2228 --------------------------------------------------------------------------*/
2229
2230int hdd_handle_batch_scan_ioctl
2231(
2232 hdd_adapter_t *pAdapter,
2233 hdd_priv_data_t *pPrivdata,
2234 tANI_U8 *command
2235)
2236{
2237 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002238 hdd_context_t *pHddCtx;
2239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
Yue Mae36e3552014-03-05 17:06:20 -08002242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2243 ret = wlan_hdd_validate_context(pHddCtx);
2244 if (ret)
2245 {
Yue Mae36e3552014-03-05 17:06:20 -08002246 goto exit;
2247 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002248
2249 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2250 {
2251 char extra[32];
2252 tANI_U8 len = 0;
2253 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2254
2255 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2256 {
2257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2258 "%s: Batch scan feature is not supported by FW", __func__);
2259 ret = -EINVAL;
2260 goto exit;
2261 }
2262
2263 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2264 version);
2265 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2266 {
2267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2268 "%s: failed to copy data to user buffer", __func__);
2269 ret = -EFAULT;
2270 goto exit;
2271 }
2272 ret = HDD_BATCH_SCAN_VERSION;
2273 }
2274 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2275 {
2276 int status;
2277 tANI_U8 *value = (command + 16);
2278 eHalStatus halStatus;
2279 unsigned long rc;
2280 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2281 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2282
2283 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2284 {
2285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2286 "%s: Batch scan feature is not supported by FW", __func__);
2287 ret = -EINVAL;
2288 goto exit;
2289 }
2290
2291 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2292 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2293 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2294 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2295 {
2296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302297 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002298 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302299 hdd_device_modetoString(pAdapter->device_mode),
2300 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002301 ret = -EINVAL;
2302 goto exit;
2303 }
2304
2305 status = hdd_parse_set_batchscan_command(value, pReq);
2306 if (status)
2307 {
2308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2309 "Invalid WLS_BATCHING SET command");
2310 ret = -EINVAL;
2311 goto exit;
2312 }
2313
2314
2315 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2316 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2317 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2318 pAdapter);
2319
2320 if ( eHAL_STATUS_SUCCESS == halStatus )
2321 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302322 char extra[32];
2323 tANI_U8 len = 0;
2324 tANI_U8 mScan = 0;
2325
Rajeev Kumar8b373292014-01-08 20:36:55 -08002326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2327 "sme_SetBatchScanReq returned success halStatus %d",
2328 halStatus);
2329 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2330 {
2331 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2332 rc = wait_for_completion_timeout(
2333 &pAdapter->hdd_set_batch_scan_req_var,
2334 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2335 if (0 == rc)
2336 {
2337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2338 "%s: Timeout waiting for set batch scan to complete",
2339 __func__);
2340 ret = -EINVAL;
2341 goto exit;
2342 }
2343 }
2344 if ( !pRsp->nScansToBatch )
2345 {
2346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "%s: Received set batch scan failure response from FW",
2348 __func__);
2349 ret = -EINVAL;
2350 goto exit;
2351 }
2352 /*As per the Batch Scan Framework API we should return the MIN of
2353 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302354 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002355
2356 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2357
2358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302360 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2361 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2362 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2363 {
2364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2365 "%s: failed to copy MSCAN value to user buffer", __func__);
2366 ret = -EFAULT;
2367 goto exit;
2368 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002369 }
2370 else
2371 {
2372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "sme_SetBatchScanReq returned failure halStatus %d",
2374 halStatus);
2375 ret = -EINVAL;
2376 goto exit;
2377 }
2378 }
2379 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2380 {
2381 eHalStatus halStatus;
2382 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2383 pInd->param = 0;
2384
2385 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "%s: Batch scan feature is not supported by FW", __func__);
2389 ret = -EINVAL;
2390 goto exit;
2391 }
2392
2393 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2394 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002396 "Batch scan is not yet enabled batch scan state %d",
2397 pAdapter->batchScanState);
2398 ret = -EINVAL;
2399 goto exit;
2400 }
2401
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002402 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2403 hdd_deinit_batch_scan(pAdapter);
2404 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2405
Rajeev Kumar8b373292014-01-08 20:36:55 -08002406 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2407
2408 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2409 pAdapter->sessionId);
2410 if ( eHAL_STATUS_SUCCESS == halStatus )
2411 {
2412 ret = 0;
2413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2414 "sme_StopBatchScanInd returned success halStatus %d",
2415 halStatus);
2416 }
2417 else
2418 {
2419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2420 "sme_StopBatchScanInd returned failure halStatus %d",
2421 halStatus);
2422 ret = -EINVAL;
2423 goto exit;
2424 }
2425 }
2426 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2427 {
2428 tANI_U32 remain_len;
2429
2430 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2431 {
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2433 "%s: Batch scan feature is not supported by FW", __func__);
2434 ret = -EINVAL;
2435 goto exit;
2436 }
2437
2438 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2439 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002441 "Batch scan is not yet enabled could not return results"
2442 "Batch Scan state %d",
2443 pAdapter->batchScanState);
2444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
2448 pPrivdata->used_len = 16;
2449 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2450 if (remain_len < pPrivdata->total_len)
2451 {
2452 /*Clear previous batch scan response data if any*/
2453 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2454 }
2455 else
2456 {
2457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2458 "Invalid total length from user space can't fetch batch"
2459 " scan response total_len %d used_len %d remain len %d",
2460 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2461 ret = -EINVAL;
2462 goto exit;
2463 }
2464 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2465 }
2466
2467exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302468 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002469 return ret;
2470}
2471
2472
Rajeev79dbe4c2013-10-05 11:03:42 +05302473#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2474
c_hpothu92367912014-05-01 15:18:17 +05302475static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2476{
c_hpothu39eb1e32014-06-26 16:31:50 +05302477 bcnMissRateContext_t *pCBCtx;
2478
2479 if (NULL == data)
2480 {
2481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2482 return;
2483 }
c_hpothu92367912014-05-01 15:18:17 +05302484
2485 /* there is a race condition that exists between this callback
2486 function and the caller since the caller could time out either
2487 before or while this code is executing. we use a spinlock to
2488 serialize these actions */
2489 spin_lock(&hdd_context_lock);
2490
c_hpothu39eb1e32014-06-26 16:31:50 +05302491 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302492 gbcnMissRate = -1;
2493
c_hpothu39eb1e32014-06-26 16:31:50 +05302494 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302495 {
2496 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302497 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302498 spin_unlock(&hdd_context_lock);
2499 return ;
2500 }
2501
2502 if (VOS_STATUS_SUCCESS == status)
2503 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302504 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302505 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302506 else
2507 {
2508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2509 }
2510
c_hpothu92367912014-05-01 15:18:17 +05302511 complete(&(pCBCtx->completion));
2512 spin_unlock(&hdd_context_lock);
2513
2514 return;
2515}
2516
Abhishek Singh08aa7762014-12-16 13:59:03 +05302517void hdd_FWStatisCB( VOS_STATUS status,
2518 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302519{
2520 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302521 hdd_adapter_t *pAdapter;
2522
2523 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2524
Abhishek Singh08aa7762014-12-16 13:59:03 +05302525 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2528 return;
2529 }
2530 /* there is a race condition that exists between this callback
2531 function and the caller since the caller could time out either
2532 before or while this code is executing. we use a spinlock to
2533 serialize these actions */
2534 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302535 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302536 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2537 {
2538 hddLog(VOS_TRACE_LEVEL_ERROR,
2539 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2540 spin_unlock(&hdd_context_lock);
2541 return;
2542 }
2543 pAdapter = fwStatsCtx->pAdapter;
2544 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2545 {
2546 hddLog(VOS_TRACE_LEVEL_ERROR,
2547 FL("pAdapter returned is NULL or invalid"));
2548 spin_unlock(&hdd_context_lock);
2549 return;
2550 }
2551 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302552 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302553 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302554 switch( fwStatsResult->type )
2555 {
2556 case FW_UBSP_STATS:
2557 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302558 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302559 hddLog(VOS_TRACE_LEVEL_INFO,
2560 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302561 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2562 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302563 }
2564 break;
2565 default:
2566 {
2567 hddLog(VOS_TRACE_LEVEL_ERROR,
2568 FL(" No handling for stats type %d"),fwStatsResult->type);
2569 }
2570 }
2571 }
2572 complete(&(fwStatsCtx->completion));
2573 spin_unlock(&hdd_context_lock);
2574 return;
2575}
2576
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302577static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2578{
2579 int ret = 0;
2580
2581 if (!pCfg || !command || !extra || !len)
2582 {
2583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2584 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2585 ret = -EINVAL;
2586 return ret;
2587 }
2588
2589 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2590 {
2591 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2592 (int)pCfg->nActiveMaxChnTime);
2593 return ret;
2594 }
2595 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2596 {
2597 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2598 (int)pCfg->nActiveMinChnTime);
2599 return ret;
2600 }
2601 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2602 {
2603 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2604 (int)pCfg->nPassiveMaxChnTime);
2605 return ret;
2606 }
2607 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2608 {
2609 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2610 (int)pCfg->nPassiveMinChnTime);
2611 return ret;
2612 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302613 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2614 {
2615 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2616 (int)pCfg->nActiveMaxChnTime);
2617 return ret;
2618 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302619 else
2620 {
2621 ret = -EINVAL;
2622 }
2623
2624 return ret;
2625}
2626
2627static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2628{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302629 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302630 hdd_config_t *pCfg;
2631 tANI_U8 *value = command;
2632 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302633 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302634
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302635 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2636 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302637 {
2638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2639 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2640 ret = -EINVAL;
2641 return ret;
2642 }
2643
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302644 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2645 sme_GetConfigParam(hHal, &smeConfig);
2646
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302647 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2648 {
2649 value = value + 24;
2650 temp = kstrtou32(value, 10, &val);
2651 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2652 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2653 {
2654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2655 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2656 ret = -EFAULT;
2657 return ret;
2658 }
2659 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302660 smeConfig.csrConfig.nActiveMaxChnTime = val;
2661 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302662 }
2663 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2664 {
2665 value = value + 24;
2666 temp = kstrtou32(value, 10, &val);
2667 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2668 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2669 {
2670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2671 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2672 ret = -EFAULT;
2673 return ret;
2674 }
2675 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302676 smeConfig.csrConfig.nActiveMinChnTime = val;
2677 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302678 }
2679 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2680 {
2681 value = value + 25;
2682 temp = kstrtou32(value, 10, &val);
2683 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2684 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2685 {
2686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2687 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2688 ret = -EFAULT;
2689 return ret;
2690 }
2691 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302692 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2693 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302694 }
2695 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2696 {
2697 value = value + 25;
2698 temp = kstrtou32(value, 10, &val);
2699 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2700 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2701 {
2702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2703 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2704 ret = -EFAULT;
2705 return ret;
2706 }
2707 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302708 smeConfig.csrConfig.nPassiveMinChnTime = val;
2709 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302710 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302711 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2712 {
2713 value = value + 13;
2714 temp = kstrtou32(value, 10, &val);
2715 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2716 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2717 {
2718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2719 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2720 ret = -EFAULT;
2721 return ret;
2722 }
2723 pCfg->nActiveMaxChnTime = val;
2724 smeConfig.csrConfig.nActiveMaxChnTime = val;
2725 sme_UpdateConfig(hHal, &smeConfig);
2726 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302727 else
2728 {
2729 ret = -EINVAL;
2730 }
2731
2732 return ret;
2733}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302734static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2735 tANI_U8 cmd_len)
2736{
2737 tANI_U8 *value;
2738 tANI_U8 fcc_constraint;
2739
2740 eHalStatus status;
2741 int ret = 0;
2742 value = cmd + cmd_len + 1;
2743
2744 ret = kstrtou8(value, 10, &fcc_constraint);
2745 if ((ret < 0) || (fcc_constraint > 1)) {
2746 /*
2747 * If the input value is greater than max value of datatype,
2748 * then also it is a failure
2749 */
2750 hddLog(VOS_TRACE_LEVEL_ERROR,
2751 "%s: value out of range", __func__);
2752 return -EINVAL;
2753 }
2754
2755 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2756 if (status != eHAL_STATUS_SUCCESS)
2757 ret = -EPERM;
2758
2759 return ret;
2760}
2761
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302762/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302763
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302764 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2765 FW will send *ONE* CA ind to Host(even though it is duplicate).
2766 When Host send IOCTL (disable), FW doesn't perform any action.
2767 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2768 sends CA ind to host. (regard less of IOCTL status)
2769 \param - pHddCtx - HDD context
2770 \param - command - command received from framework
2771 \param - cmd_len - len of the command
2772
2773 \return - 0 on success, appropriate error values on failure.
2774
2775 --------------------------------------------------------------------------*/
2776int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2777{
2778 tANI_U8 set_value;
2779 int ret = 0;
2780 eHalStatus status;
2781
2782 ret = wlan_hdd_validate_context(pHddCtx);
2783 if (0 != ret)
2784 {
2785 ret = -EINVAL;
2786 goto exit;
2787 }
2788
2789 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2790 {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2792 " ini param to control channel avooidance indication");
2793 ret = 0;
2794 goto exit;
2795 }
2796
2797 set_value = command[cmd_len + 1] - '0';
2798 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2799 if (status != eHAL_STATUS_SUCCESS)
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2802 " enableDisableChanAoidance command to SME\n", __func__);
2803 ret = -EINVAL;
2804 }
2805
2806exit:
2807 return ret;
2808}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302809
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05302810/**
2811 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
2812 * @pHddCtx: Pointer to the HDD context
2813 * @channel: channel to reassociate
2814 * @targetApBssid: Target AP/BSSID to reassociate
2815 *
2816 * Return: None
2817 */
2818#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
2819static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
2820 uint8_t channel, tSirMacAddr targetApBssid)
2821{
2822 tCsrHandoffRequest handoffInfo;
2823 handoffInfo.channel = channel;
2824 handoffInfo.src = FASTREASSOC;
2825 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
2826 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2827}
2828#else
2829static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
2830 uint8_t channel, tSirMacAddr targetApBssid)
2831{
2832}
2833#endif
2834
2835/**
2836 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
2837 * @pAdapter: Pointer to HDD adapter
2838 * @channel: Channel to scan/roam
2839 * @targetApBssid: BSSID to roam
2840 *
2841 * Return: None
2842 */
2843#ifdef QCA_WIFI_ISOC
2844static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
2845 uint8_t channel, tSirMacAddr targetApBssid)
2846{
2847 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
2848 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
2849}
2850#else
2851static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
2852 uint8_t channel, tSirMacAddr targetApBssid)
2853{
2854}
2855#endif
2856
2857/**
2858 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
2859 * @pAdapter: pointer to hdd adapter
2860 * @command: pointer to the command received
2861 *
2862 * Return: VOS_STATUS enum
2863 */
2864static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
2865 uint8_t *command)
2866{
2867 tANI_U8 *value = command;
2868 tANI_U8 channel = 0;
2869 tSirMacAddr targetApBssid;
2870 eHalStatus status = eHAL_STATUS_SUCCESS;
2871 hdd_station_ctx_t *pHddStaCtx = NULL;
2872 hdd_context_t *pHddCtx = NULL;
2873 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2874 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2875
2876 /* if not associated, no need to proceed with reassoc */
2877 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2878 hddLog(LOG1, FL("Not associated!"));
2879 return eHAL_STATUS_FAILURE;
2880 }
2881
2882 status = hdd_parse_reassoc_command_data(value, targetApBssid,
2883 &channel);
2884 if (eHAL_STATUS_SUCCESS != status) {
2885 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2886 return eHAL_STATUS_FAILURE;
2887 }
2888
2889 /* if the target bssid is same as currently associated AP,
2890 then no need to proceed with reassoc */
2891 if (vos_mem_compare(targetApBssid,
2892 pHddStaCtx->conn_info.bssId,
2893 sizeof(tSirMacAddr))) {
2894 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2895 return eHAL_STATUS_FAILURE;
2896 }
2897
2898 /* Check channel number is a valid channel number */
2899 if (VOS_STATUS_SUCCESS !=
2900 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2901 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
2902 return eHAL_STATUS_FAILURE;
2903 }
2904
2905 /* Proceed with reassoc */
2906 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
2907
2908 /* Proceed with scan/roam */
2909 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
2910
2911 return eHAL_STATUS_SUCCESS;
2912}
2913
2914/**
2915 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
2916 * @handoffInfo: Pointer to the csr Handoff Request.
2917 *
2918 * Return: None
2919 */
2920#ifndef QCA_WIFI_ISOC
2921static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
2922{
2923 handoffInfo->src = REASSOC;
2924}
2925#else
2926static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
2927{
2928}
2929#endif
2930
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002931static int hdd_driver_command(hdd_adapter_t *pAdapter,
2932 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002933{
Jeff Johnson295189b2012-06-20 16:38:30 -07002934 hdd_priv_data_t priv_data;
2935 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302936 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2937 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002938 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302939 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2941 struct cfg80211_mgmt_tx_params params;
2942#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302943
2944 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002945 /*
2946 * Note that valid pointers are provided by caller
2947 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002948
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002949 /* copy to local struct to avoid numerous changes to legacy code */
2950 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002951
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002952 if (priv_data.total_len <= 0 ||
2953 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002954 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002955 hddLog(VOS_TRACE_LEVEL_WARN,
2956 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2957 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002958 ret = -EINVAL;
2959 goto exit;
2960 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302961 status = wlan_hdd_validate_context(pHddCtx);
2962 if (0 != status)
2963 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302964 ret = -EINVAL;
2965 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302966 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002967 /* Allocate +1 for '\0' */
2968 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 if (!command)
2970 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002971 hddLog(VOS_TRACE_LEVEL_ERROR,
2972 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 ret = -ENOMEM;
2974 goto exit;
2975 }
2976
2977 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2978 {
2979 ret = -EFAULT;
2980 goto exit;
2981 }
2982
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002983 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002984 command[priv_data.total_len] = '\0';
2985
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002986 /* at one time the following block of code was conditional. braces
2987 * have been retained to avoid re-indenting the legacy code
2988 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002989 {
2990 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2991
2992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002993 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002994
2995 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2996 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302997 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2998 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2999 pAdapter->sessionId, (unsigned)
3000 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3001 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3002 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3003 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003004 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3005 sizeof(tSirMacAddr)))
3006 {
3007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003008 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003009 ret = -EFAULT;
3010 }
3011 }
Amar Singhal0974e402013-02-12 14:27:46 -08003012 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003013 {
Amar Singhal0974e402013-02-12 14:27:46 -08003014 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003015
Jeff Johnson295189b2012-06-20 16:38:30 -07003016 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003017
3018 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003019 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003021 "%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 +05303022 if(VOS_FTM_MODE != hdd_get_conparam())
3023 {
3024 /* Change band request received */
3025 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3026 if(ret < 0)
3027 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3028 "%s: failed to set band ret=%d", __func__, ret);
3029 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003030 }
Kiet Lamf040f472013-11-20 21:15:23 +05303031 else if(strncmp(command, "SETWMMPS", 8) == 0)
3032 {
3033 tANI_U8 *ptr = command;
3034 ret = hdd_wmmps_helper(pAdapter, ptr);
3035 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303036
3037 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3038 {
3039 tANI_U8 *ptr = command;
3040 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3041 }
3042
Jeff Johnson32d95a32012-09-10 13:15:23 -07003043 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3044 {
3045 char *country_code;
3046
3047 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003048
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003049 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003050 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003051#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303052 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003053#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003054 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3055 (void *)(tSmeChangeCountryCallback)
3056 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303057 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003058 if (eHAL_STATUS_SUCCESS == ret)
3059 {
3060 ret = wait_for_completion_interruptible_timeout(
3061 &pAdapter->change_country_code,
3062 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3063 if (0 >= ret)
3064 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303066 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003067 }
3068 }
3069 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003070 {
3071 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003072 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003073 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003074 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003075
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003076 }
3077 /*
3078 command should be a string having format
3079 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3080 */
Amar Singhal0974e402013-02-12 14:27:46 -08003081 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003082 {
Amar Singhal0974e402013-02-12 14:27:46 -08003083 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003084
3085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003086 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003087
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003088 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003089 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003090 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3091 {
3092 int suspend = 0;
3093 tANI_U8 *ptr = (tANI_U8*)command + 15;
3094
3095 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3097 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3098 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003099 hdd_set_wlan_suspend_mode(suspend);
3100 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003101#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3102 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3103 {
3104 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003105 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003106 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3107 eHalStatus status = eHAL_STATUS_SUCCESS;
3108
3109 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3110 value = value + 15;
3111
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003112 /* Convert the value from ascii to integer */
3113 ret = kstrtos8(value, 10, &rssi);
3114 if (ret < 0)
3115 {
3116 /* If the input value is greater than max value of datatype, then also
3117 kstrtou8 fails */
3118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3119 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003120 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003121 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3122 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3123 ret = -EINVAL;
3124 goto exit;
3125 }
3126
Srinivas Girigowdade697412013-02-14 16:31:48 -08003127 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003128
Srinivas Girigowdade697412013-02-14 16:31:48 -08003129 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3130 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3131 {
3132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3133 "Neighbor lookup threshold value %d is out of range"
3134 " (Min: %d Max: %d)", lookUpThreshold,
3135 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3136 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3137 ret = -EINVAL;
3138 goto exit;
3139 }
3140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3142 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3143 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3145 "%s: Received Command to Set Roam trigger"
3146 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3147
3148 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3149 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3150 if (eHAL_STATUS_SUCCESS != status)
3151 {
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3153 "%s: Failed to set roam trigger, try again", __func__);
3154 ret = -EPERM;
3155 goto exit;
3156 }
3157
3158 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303159 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003160 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3161 }
3162 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3163 {
3164 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3165 int rssi = (-1) * lookUpThreshold;
3166 char extra[32];
3167 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3169 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3170 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003171 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303172 len = VOS_MIN(priv_data.total_len, len + 1);
3173 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003174 {
3175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3176 "%s: failed to copy data to user buffer", __func__);
3177 ret = -EFAULT;
3178 goto exit;
3179 }
3180 }
3181 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3182 {
3183 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003184 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003185 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003186
Srinivas Girigowdade697412013-02-14 16:31:48 -08003187 /* input refresh period is in terms of seconds */
3188 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3189 value = value + 18;
3190 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003191 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003192 if (ret < 0)
3193 {
3194 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003195 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003197 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003198 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003199 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3200 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003201 ret = -EINVAL;
3202 goto exit;
3203 }
3204
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003205 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3206 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003209 "Roam scan period value %d is out of range"
3210 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003211 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3212 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003213 ret = -EINVAL;
3214 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303215 }
3216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3217 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3218 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003219 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003220
3221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3222 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003223 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003224
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003225 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3226 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003227 }
3228 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3229 {
3230 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3231 char extra[32];
3232 tANI_U8 len = 0;
3233
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3235 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3236 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003237 len = scnprintf(extra, sizeof(extra), "%s %d",
3238 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003239 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303240 len = VOS_MIN(priv_data.total_len, len + 1);
3241 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3243 "%s: failed to copy data to user buffer", __func__);
3244 ret = -EFAULT;
3245 goto exit;
3246 }
3247 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003248 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3249 {
3250 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003251 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003252 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003253
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003254 /* input refresh period is in terms of seconds */
3255 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3256 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003257
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003258 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003259 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003260 if (ret < 0)
3261 {
3262 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003263 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003265 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003266 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003267 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3268 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3269 ret = -EINVAL;
3270 goto exit;
3271 }
3272
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003273 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3274 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3275 {
3276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3277 "Neighbor scan results refresh period value %d is out of range"
3278 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3279 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3280 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3281 ret = -EINVAL;
3282 goto exit;
3283 }
3284 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3285
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3287 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003288 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003289
3290 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3291 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3292 }
3293 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3294 {
3295 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3296 char extra[32];
3297 tANI_U8 len = 0;
3298
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003299 len = scnprintf(extra, sizeof(extra), "%s %d",
3300 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003301 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303302 len = VOS_MIN(priv_data.total_len, len + 1);
3303 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3305 "%s: failed to copy data to user buffer", __func__);
3306 ret = -EFAULT;
3307 goto exit;
3308 }
3309 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003310#ifdef FEATURE_WLAN_LFR
3311 /* SETROAMMODE */
3312 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3313 {
3314 tANI_U8 *value = command;
3315 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3316
3317 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3318 value = value + SIZE_OF_SETROAMMODE + 1;
3319
3320 /* Convert the value from ascii to integer */
3321 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3322 if (ret < 0)
3323 {
3324 /* If the input value is greater than max value of datatype, then also
3325 kstrtou8 fails */
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s: kstrtou8 failed range [%d - %d]", __func__,
3328 CFG_LFR_FEATURE_ENABLED_MIN,
3329 CFG_LFR_FEATURE_ENABLED_MAX);
3330 ret = -EINVAL;
3331 goto exit;
3332 }
3333 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3334 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "Roam Mode value %d is out of range"
3338 " (Min: %d Max: %d)", roamMode,
3339 CFG_LFR_FEATURE_ENABLED_MIN,
3340 CFG_LFR_FEATURE_ENABLED_MAX);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344
3345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3346 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3347 /*
3348 * Note that
3349 * SETROAMMODE 0 is to enable LFR while
3350 * SETROAMMODE 1 is to disable LFR, but
3351 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3352 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3353 */
3354 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3355 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3356 else
3357 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3358
3359 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3360 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3361 }
3362 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303363 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003364 {
3365 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3366 char extra[32];
3367 tANI_U8 len = 0;
3368
3369 /*
3370 * roamMode value shall be inverted because the sementics is different.
3371 */
3372 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3373 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3374 else
3375 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3376
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003377 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303378 len = VOS_MIN(priv_data.total_len, len + 1);
3379 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3381 "%s: failed to copy data to user buffer", __func__);
3382 ret = -EFAULT;
3383 goto exit;
3384 }
3385 }
3386#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003387#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003388#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003389 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3390 {
3391 tANI_U8 *value = command;
3392 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3393
3394 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3395 value = value + 13;
3396 /* Convert the value from ascii to integer */
3397 ret = kstrtou8(value, 10, &roamRssiDiff);
3398 if (ret < 0)
3399 {
3400 /* If the input value is greater than max value of datatype, then also
3401 kstrtou8 fails */
3402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3403 "%s: kstrtou8 failed range [%d - %d]", __func__,
3404 CFG_ROAM_RSSI_DIFF_MIN,
3405 CFG_ROAM_RSSI_DIFF_MAX);
3406 ret = -EINVAL;
3407 goto exit;
3408 }
3409
3410 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3411 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3412 {
3413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3414 "Roam rssi diff value %d is out of range"
3415 " (Min: %d Max: %d)", roamRssiDiff,
3416 CFG_ROAM_RSSI_DIFF_MIN,
3417 CFG_ROAM_RSSI_DIFF_MAX);
3418 ret = -EINVAL;
3419 goto exit;
3420 }
3421
3422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3423 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3424
3425 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3426 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3427 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303428 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003429 {
3430 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3431 char extra[32];
3432 tANI_U8 len = 0;
3433
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303434 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3435 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3436 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003437 len = scnprintf(extra, sizeof(extra), "%s %d",
3438 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303439 len = VOS_MIN(priv_data.total_len, len + 1);
3440 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3442 "%s: failed to copy data to user buffer", __func__);
3443 ret = -EFAULT;
3444 goto exit;
3445 }
3446 }
3447#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003448#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003449 else if (strncmp(command, "GETBAND", 7) == 0)
3450 {
3451 int band = -1;
3452 char extra[32];
3453 tANI_U8 len = 0;
3454 hdd_getBand_helper(pHddCtx, &band);
3455
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303456 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3457 TRACE_CODE_HDD_GETBAND_IOCTL,
3458 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003459 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303460 len = VOS_MIN(priv_data.total_len, len + 1);
3461 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3463 "%s: failed to copy data to user buffer", __func__);
3464 ret = -EFAULT;
3465 goto exit;
3466 }
3467 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003468 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3469 {
3470 tANI_U8 *value = command;
3471 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3472 tANI_U8 numChannels = 0;
3473 eHalStatus status = eHAL_STATUS_SUCCESS;
3474
3475 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3476 if (eHAL_STATUS_SUCCESS != status)
3477 {
3478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3479 "%s: Failed to parse channel list information", __func__);
3480 ret = -EINVAL;
3481 goto exit;
3482 }
3483
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303484 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3485 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3486 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003487 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3488 {
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3491 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3492 ret = -EINVAL;
3493 goto exit;
3494 }
3495 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3496 numChannels);
3497 if (eHAL_STATUS_SUCCESS != status)
3498 {
3499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3500 "%s: Failed to update channel list information", __func__);
3501 ret = -EINVAL;
3502 goto exit;
3503 }
3504 }
3505 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3506 {
3507 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3508 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003509 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003510 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003511 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003512
3513 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3514 ChannelList, &numChannels ))
3515 {
3516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3517 "%s: failed to get roam scan channel list", __func__);
3518 ret = -EFAULT;
3519 goto exit;
3520 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3522 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3523 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003524 /* output channel list is of the format
3525 [Number of roam scan channels][Channel1][Channel2]... */
3526 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003527 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303528 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003529 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003530 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3531 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003532 }
3533
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303534 len = VOS_MIN(priv_data.total_len, len + 1);
3535 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003536 {
3537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3538 "%s: failed to copy data to user buffer", __func__);
3539 ret = -EFAULT;
3540 goto exit;
3541 }
3542 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003543 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3544 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003545 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003546 char extra[32];
3547 tANI_U8 len = 0;
3548
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003549 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003550 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003551 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003552 hdd_is_okc_mode_enabled(pHddCtx) &&
3553 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3554 {
3555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003556 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003557 " hence this operation is not permitted!", __func__);
3558 ret = -EPERM;
3559 goto exit;
3560 }
3561
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003562 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003563 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303564 len = VOS_MIN(priv_data.total_len, len + 1);
3565 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003566 {
3567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3568 "%s: failed to copy data to user buffer", __func__);
3569 ret = -EFAULT;
3570 goto exit;
3571 }
3572 }
3573 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3574 {
3575 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3576 char extra[32];
3577 tANI_U8 len = 0;
3578
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003579 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003580 then this operation is not permitted (return FAILURE) */
3581 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003582 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003583 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3584 {
3585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003586 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003587 " hence this operation is not permitted!", __func__);
3588 ret = -EPERM;
3589 goto exit;
3590 }
3591
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003592 len = scnprintf(extra, sizeof(extra), "%s %d",
3593 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303594 len = VOS_MIN(priv_data.total_len, len + 1);
3595 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003596 {
3597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3598 "%s: failed to copy data to user buffer", __func__);
3599 ret = -EFAULT;
3600 goto exit;
3601 }
3602 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003603 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003604 {
3605 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3606 char extra[32];
3607 tANI_U8 len = 0;
3608
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003609 len = scnprintf(extra, sizeof(extra), "%s %d",
3610 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303611 len = VOS_MIN(priv_data.total_len, len + 1);
3612 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003613 {
3614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3615 "%s: failed to copy data to user buffer", __func__);
3616 ret = -EFAULT;
3617 goto exit;
3618 }
3619 }
3620 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3621 {
3622 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3623 char extra[32];
3624 tANI_U8 len = 0;
3625
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003626 len = scnprintf(extra, sizeof(extra), "%s %d",
3627 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303628 len = VOS_MIN(priv_data.total_len, len + 1);
3629 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003630 {
3631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3632 "%s: failed to copy data to user buffer", __func__);
3633 ret = -EFAULT;
3634 goto exit;
3635 }
3636 }
3637 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3638 {
3639 tANI_U8 *value = command;
3640 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3641
3642 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3643 value = value + 26;
3644 /* Convert the value from ascii to integer */
3645 ret = kstrtou8(value, 10, &minTime);
3646 if (ret < 0)
3647 {
3648 /* If the input value is greater than max value of datatype, then also
3649 kstrtou8 fails */
3650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3651 "%s: kstrtou8 failed range [%d - %d]", __func__,
3652 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3653 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3654 ret = -EINVAL;
3655 goto exit;
3656 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003657 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3658 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3659 {
3660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3661 "scan min channel time value %d is out of range"
3662 " (Min: %d Max: %d)", minTime,
3663 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3664 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3665 ret = -EINVAL;
3666 goto exit;
3667 }
3668
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303669 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3670 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3671 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3673 "%s: Received Command to change channel min time = %d", __func__, minTime);
3674
3675 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3676 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3677 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003678 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3679 {
3680 tANI_U8 *value = command;
3681 tANI_U8 channel = 0;
3682 tANI_U8 dwellTime = 0;
3683 tANI_U8 bufLen = 0;
3684 tANI_U8 *buf = NULL;
3685 tSirMacAddr targetApBssid;
3686 eHalStatus status = eHAL_STATUS_SUCCESS;
3687 struct ieee80211_channel chan;
3688 tANI_U8 finalLen = 0;
3689 tANI_U8 *finalBuf = NULL;
3690 tANI_U8 temp = 0;
3691 u64 cookie;
3692 hdd_station_ctx_t *pHddStaCtx = NULL;
3693 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3694
3695 /* if not associated, no need to send action frame */
3696 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3697 {
3698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3699 ret = -EINVAL;
3700 goto exit;
3701 }
3702
3703 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3704 &dwellTime, &buf, &bufLen);
3705 if (eHAL_STATUS_SUCCESS != status)
3706 {
3707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3708 "%s: Failed to parse send action frame data", __func__);
3709 ret = -EINVAL;
3710 goto exit;
3711 }
3712
3713 /* if the target bssid is different from currently associated AP,
3714 then no need to send action frame */
3715 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3716 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3717 {
3718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3719 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003720 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003721 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003722 goto exit;
3723 }
3724
3725 /* if the channel number is different from operating channel then
3726 no need to send action frame */
3727 if (channel != pHddStaCtx->conn_info.operationChannel)
3728 {
3729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3730 "%s: channel(%d) is different from operating channel(%d)",
3731 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3732 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003733 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003734 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003735 goto exit;
3736 }
3737 chan.center_freq = sme_ChnToFreq(channel);
3738
3739 finalLen = bufLen + 24;
3740 finalBuf = vos_mem_malloc(finalLen);
3741 if (NULL == finalBuf)
3742 {
3743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3744 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003745 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003746 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003747 goto exit;
3748 }
3749 vos_mem_zero(finalBuf, finalLen);
3750
3751 /* Fill subtype */
3752 temp = SIR_MAC_MGMT_ACTION << 4;
3753 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3754
3755 /* Fill type */
3756 temp = SIR_MAC_MGMT_FRAME;
3757 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3758
3759 /* Fill destination address (bssid of the AP) */
3760 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3761
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003762 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003763 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3764
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003765 /* Fill BSSID (AP mac address) */
3766 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003767
3768 /* Fill received buffer from 24th address */
3769 vos_mem_copy(finalBuf + 24, buf, bufLen);
3770
Jeff Johnson11c33152013-04-16 17:52:40 -07003771 /* done with the parsed buffer */
3772 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003773 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003774
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3776 params.chan = &chan;
3777 params.offchan = 0;
3778 params.wait = dwellTime;
3779 params.buf = finalBuf;
3780 params.len = finalLen;
3781 params.no_cck = 1;
3782 params.dont_wait_for_ack = 1;
3783 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3784#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303785 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3787 &(pAdapter->wdev),
3788#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003789 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003790#endif
3791 &chan, 0,
3792#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3793 NL80211_CHAN_HT20, 1,
3794#endif
3795 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003796 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303797#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003798 vos_mem_free(finalBuf);
3799 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003800 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3801 {
3802 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3803 char extra[32];
3804 tANI_U8 len = 0;
3805
3806 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003807 len = scnprintf(extra, sizeof(extra), "%s %d",
3808 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303809 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3810 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3811 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303812 len = VOS_MIN(priv_data.total_len, len + 1);
3813 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003814 {
3815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3816 "%s: failed to copy data to user buffer", __func__);
3817 ret = -EFAULT;
3818 goto exit;
3819 }
3820 }
3821 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3822 {
3823 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003824 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003825
3826 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3827 value = value + 19;
3828 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003829 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003830 if (ret < 0)
3831 {
3832 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003833 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003835 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003836 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3837 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3838 ret = -EINVAL;
3839 goto exit;
3840 }
3841
3842 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3843 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3844 {
3845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3846 "lfr mode value %d is out of range"
3847 " (Min: %d Max: %d)", maxTime,
3848 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3849 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3850 ret = -EINVAL;
3851 goto exit;
3852 }
3853
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3855 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3856
3857 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3858 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3859 }
3860 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3861 {
3862 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3863 char extra[32];
3864 tANI_U8 len = 0;
3865
3866 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003867 len = scnprintf(extra, sizeof(extra), "%s %d",
3868 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303869 len = VOS_MIN(priv_data.total_len, len + 1);
3870 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003871 {
3872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3873 "%s: failed to copy data to user buffer", __func__);
3874 ret = -EFAULT;
3875 goto exit;
3876 }
3877 }
3878 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3879 {
3880 tANI_U8 *value = command;
3881 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3882
3883 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3884 value = value + 16;
3885 /* Convert the value from ascii to integer */
3886 ret = kstrtou16(value, 10, &val);
3887 if (ret < 0)
3888 {
3889 /* If the input value is greater than max value of datatype, then also
3890 kstrtou16 fails */
3891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3892 "%s: kstrtou16 failed range [%d - %d]", __func__,
3893 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3894 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3895 ret = -EINVAL;
3896 goto exit;
3897 }
3898
3899 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3900 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3901 {
3902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3903 "scan home time value %d is out of range"
3904 " (Min: %d Max: %d)", val,
3905 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3906 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3907 ret = -EINVAL;
3908 goto exit;
3909 }
3910
3911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3912 "%s: Received Command to change scan home time = %d", __func__, val);
3913
3914 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3915 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3916 }
3917 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3918 {
3919 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3920 char extra[32];
3921 tANI_U8 len = 0;
3922
3923 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003924 len = scnprintf(extra, sizeof(extra), "%s %d",
3925 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303926 len = VOS_MIN(priv_data.total_len, len + 1);
3927 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003928 {
3929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3930 "%s: failed to copy data to user buffer", __func__);
3931 ret = -EFAULT;
3932 goto exit;
3933 }
3934 }
3935 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3936 {
3937 tANI_U8 *value = command;
3938 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3939
3940 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3941 value = value + 17;
3942 /* Convert the value from ascii to integer */
3943 ret = kstrtou8(value, 10, &val);
3944 if (ret < 0)
3945 {
3946 /* If the input value is greater than max value of datatype, then also
3947 kstrtou8 fails */
3948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3949 "%s: kstrtou8 failed range [%d - %d]", __func__,
3950 CFG_ROAM_INTRA_BAND_MIN,
3951 CFG_ROAM_INTRA_BAND_MAX);
3952 ret = -EINVAL;
3953 goto exit;
3954 }
3955
3956 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3957 (val > CFG_ROAM_INTRA_BAND_MAX))
3958 {
3959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3960 "intra band mode value %d is out of range"
3961 " (Min: %d Max: %d)", val,
3962 CFG_ROAM_INTRA_BAND_MIN,
3963 CFG_ROAM_INTRA_BAND_MAX);
3964 ret = -EINVAL;
3965 goto exit;
3966 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3968 "%s: Received Command to change intra band = %d", __func__, val);
3969
3970 pHddCtx->cfg_ini->nRoamIntraBand = val;
3971 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3972 }
3973 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3974 {
3975 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3976 char extra[32];
3977 tANI_U8 len = 0;
3978
3979 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003980 len = scnprintf(extra, sizeof(extra), "%s %d",
3981 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303982 len = VOS_MIN(priv_data.total_len, len + 1);
3983 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003984 {
3985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3986 "%s: failed to copy data to user buffer", __func__);
3987 ret = -EFAULT;
3988 goto exit;
3989 }
3990 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003991 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3992 {
3993 tANI_U8 *value = command;
3994 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3995
3996 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3997 value = value + 15;
3998 /* Convert the value from ascii to integer */
3999 ret = kstrtou8(value, 10, &nProbes);
4000 if (ret < 0)
4001 {
4002 /* If the input value is greater than max value of datatype, then also
4003 kstrtou8 fails */
4004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4005 "%s: kstrtou8 failed range [%d - %d]", __func__,
4006 CFG_ROAM_SCAN_N_PROBES_MIN,
4007 CFG_ROAM_SCAN_N_PROBES_MAX);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4013 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4014 {
4015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4016 "NProbes value %d is out of range"
4017 " (Min: %d Max: %d)", nProbes,
4018 CFG_ROAM_SCAN_N_PROBES_MIN,
4019 CFG_ROAM_SCAN_N_PROBES_MAX);
4020 ret = -EINVAL;
4021 goto exit;
4022 }
4023
4024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4025 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4026
4027 pHddCtx->cfg_ini->nProbes = nProbes;
4028 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4029 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304030 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004031 {
4032 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4033 char extra[32];
4034 tANI_U8 len = 0;
4035
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004036 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304037 len = VOS_MIN(priv_data.total_len, len + 1);
4038 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4040 "%s: failed to copy data to user buffer", __func__);
4041 ret = -EFAULT;
4042 goto exit;
4043 }
4044 }
4045 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4046 {
4047 tANI_U8 *value = command;
4048 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4049
4050 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4051 /* input value is in units of msec */
4052 value = value + 20;
4053 /* Convert the value from ascii to integer */
4054 ret = kstrtou16(value, 10, &homeAwayTime);
4055 if (ret < 0)
4056 {
4057 /* If the input value is greater than max value of datatype, then also
4058 kstrtou8 fails */
4059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4060 "%s: kstrtou8 failed range [%d - %d]", __func__,
4061 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4062 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4063 ret = -EINVAL;
4064 goto exit;
4065 }
4066
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004067 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4068 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4069 {
4070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4071 "homeAwayTime value %d is out of range"
4072 " (Min: %d Max: %d)", homeAwayTime,
4073 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4074 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4075 ret = -EINVAL;
4076 goto exit;
4077 }
4078
4079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4080 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004081 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4082 {
4083 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4084 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4085 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004086 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304087 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004088 {
4089 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4090 char extra[32];
4091 tANI_U8 len = 0;
4092
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004093 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304094 len = VOS_MIN(priv_data.total_len, len + 1);
4095 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4097 "%s: failed to copy data to user buffer", __func__);
4098 ret = -EFAULT;
4099 goto exit;
4100 }
4101 }
4102 else if (strncmp(command, "REASSOC", 7) == 0)
4103 {
4104 tANI_U8 *value = command;
4105 tANI_U8 channel = 0;
4106 tSirMacAddr targetApBssid;
4107 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07004108#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
4109 tCsrHandoffRequest handoffInfo;
4110#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004111 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004112 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4113
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004114 /* if not associated, no need to proceed with reassoc */
4115 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4116 {
4117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4118 ret = -EINVAL;
4119 goto exit;
4120 }
4121
4122 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
4123 if (eHAL_STATUS_SUCCESS != status)
4124 {
4125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4126 "%s: Failed to parse reassoc command data", __func__);
4127 ret = -EINVAL;
4128 goto exit;
4129 }
4130
4131 /* if the target bssid is same as currently associated AP,
4132 then no need to proceed with reassoc */
4133 if (VOS_TRUE == vos_mem_compare(targetApBssid,
4134 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4135 {
4136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
c_manjee6de1f452015-12-08 14:13:28 +05304137 ret = 0;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004138 goto exit;
4139 }
4140
4141 /* Check channel number is a valid channel number */
4142 if(VOS_STATUS_SUCCESS !=
4143 wlan_hdd_validate_operation_channel(pAdapter, channel))
4144 {
4145 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004146 "%s: Invalid Channel [%d]", __func__, channel);
c_manjee6de1f452015-12-08 14:13:28 +05304147
4148 ret = -EINVAL;
4149 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004150 }
4151
4152 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07004153#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
4154 handoffInfo.channel = channel;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304155 hdd_assign_reassoc_handoff(&handoffInfo);
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07004156 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
4157 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
4158#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004159 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004160 else if (strncmp(command, "SETWESMODE", 10) == 0)
4161 {
4162 tANI_U8 *value = command;
4163 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4164
4165 /* Move pointer to ahead of SETWESMODE<delimiter> */
4166 value = value + 11;
4167 /* Convert the value from ascii to integer */
4168 ret = kstrtou8(value, 10, &wesMode);
4169 if (ret < 0)
4170 {
4171 /* If the input value is greater than max value of datatype, then also
4172 kstrtou8 fails */
4173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4174 "%s: kstrtou8 failed range [%d - %d]", __func__,
4175 CFG_ENABLE_WES_MODE_NAME_MIN,
4176 CFG_ENABLE_WES_MODE_NAME_MAX);
4177 ret = -EINVAL;
4178 goto exit;
4179 }
4180
4181 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4182 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4183 {
4184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4185 "WES Mode value %d is out of range"
4186 " (Min: %d Max: %d)", wesMode,
4187 CFG_ENABLE_WES_MODE_NAME_MIN,
4188 CFG_ENABLE_WES_MODE_NAME_MAX);
4189 ret = -EINVAL;
4190 goto exit;
4191 }
4192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4193 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4194
4195 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4196 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4197 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304198 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004199 {
4200 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4201 char extra[32];
4202 tANI_U8 len = 0;
4203
Arif Hussain826d9412013-11-12 16:44:54 -08004204 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304205 len = VOS_MIN(priv_data.total_len, len + 1);
4206 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4208 "%s: failed to copy data to user buffer", __func__);
4209 ret = -EFAULT;
4210 goto exit;
4211 }
4212 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004213#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004214#ifdef FEATURE_WLAN_LFR
4215 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4216 {
4217 tANI_U8 *value = command;
4218 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4219
4220 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4221 value = value + 12;
4222 /* Convert the value from ascii to integer */
4223 ret = kstrtou8(value, 10, &lfrMode);
4224 if (ret < 0)
4225 {
4226 /* If the input value is greater than max value of datatype, then also
4227 kstrtou8 fails */
4228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4229 "%s: kstrtou8 failed range [%d - %d]", __func__,
4230 CFG_LFR_FEATURE_ENABLED_MIN,
4231 CFG_LFR_FEATURE_ENABLED_MAX);
4232 ret = -EINVAL;
4233 goto exit;
4234 }
4235
4236 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4237 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4238 {
4239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4240 "lfr mode value %d is out of range"
4241 " (Min: %d Max: %d)", lfrMode,
4242 CFG_LFR_FEATURE_ENABLED_MIN,
4243 CFG_LFR_FEATURE_ENABLED_MAX);
4244 ret = -EINVAL;
4245 goto exit;
4246 }
4247
4248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4249 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4250
4251 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4252 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4253 }
4254#endif
4255#ifdef WLAN_FEATURE_VOWIFI_11R
4256 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4257 {
4258 tANI_U8 *value = command;
4259 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4260
4261 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4262 value = value + 18;
4263 /* Convert the value from ascii to integer */
4264 ret = kstrtou8(value, 10, &ft);
4265 if (ret < 0)
4266 {
4267 /* If the input value is greater than max value of datatype, then also
4268 kstrtou8 fails */
4269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4270 "%s: kstrtou8 failed range [%d - %d]", __func__,
4271 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4272 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4273 ret = -EINVAL;
4274 goto exit;
4275 }
4276
4277 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4278 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4279 {
4280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4281 "ft mode value %d is out of range"
4282 " (Min: %d Max: %d)", ft,
4283 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4284 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4285 ret = -EINVAL;
4286 goto exit;
4287 }
4288
4289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4290 "%s: Received Command to change ft mode = %d", __func__, ft);
4291
4292 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4293 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4294 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304295 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4296 {
4297 tANI_U8 *value = command;
4298 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304299
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304300 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4301 value = value + 15;
4302 /* Convert the value from ascii to integer */
4303 ret = kstrtou8(value, 10, &dfsScanMode);
4304 if (ret < 0)
4305 {
4306 /* If the input value is greater than max value of
4307 datatype, then also kstrtou8 fails
4308 */
4309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4310 "%s: kstrtou8 failed range [%d - %d]", __func__,
4311 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4312 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4313 ret = -EINVAL;
4314 goto exit;
4315 }
4316
4317 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4318 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4319 {
4320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4321 "dfsScanMode value %d is out of range"
4322 " (Min: %d Max: %d)", dfsScanMode,
4323 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4324 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4325 ret = -EINVAL;
4326 goto exit;
4327 }
4328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4329 "%s: Received Command to Set DFS Scan Mode = %d",
4330 __func__, dfsScanMode);
4331
4332 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4333 }
4334 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4335 {
4336 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4337 char extra[32];
4338 tANI_U8 len = 0;
4339
4340 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304341 len = VOS_MIN(priv_data.total_len, len + 1);
4342 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304343 {
4344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4345 "%s: failed to copy data to user buffer", __func__);
4346 ret = -EFAULT;
4347 goto exit;
4348 }
4349 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304350 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4351 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304352 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4353 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304354 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304355 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004356#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004357#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004358 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4359 {
4360 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004361 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004362
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004363 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004364 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004365 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004366 hdd_is_okc_mode_enabled(pHddCtx) &&
4367 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4368 {
4369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004370 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004371 " hence this operation is not permitted!", __func__);
4372 ret = -EPERM;
4373 goto exit;
4374 }
4375
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004376 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4377 value = value + 11;
4378 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004379 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004380 if (ret < 0)
4381 {
4382 /* If the input value is greater than max value of datatype, then also
4383 kstrtou8 fails */
4384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4385 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004386 CFG_ESE_FEATURE_ENABLED_MIN,
4387 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004388 ret = -EINVAL;
4389 goto exit;
4390 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004391 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4392 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004393 {
4394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004395 "Ese mode value %d is out of range"
4396 " (Min: %d Max: %d)", eseMode,
4397 CFG_ESE_FEATURE_ENABLED_MIN,
4398 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004399 ret = -EINVAL;
4400 goto exit;
4401 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004403 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004404
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004405 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4406 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004407 }
4408#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004409 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4410 {
4411 tANI_U8 *value = command;
4412 tANI_BOOLEAN roamScanControl = 0;
4413
4414 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4415 value = value + 19;
4416 /* Convert the value from ascii to integer */
4417 ret = kstrtou8(value, 10, &roamScanControl);
4418 if (ret < 0)
4419 {
4420 /* If the input value is greater than max value of datatype, then also
4421 kstrtou8 fails */
4422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4423 "%s: kstrtou8 failed ", __func__);
4424 ret = -EINVAL;
4425 goto exit;
4426 }
4427
4428 if (0 != roamScanControl)
4429 {
4430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4431 "roam scan control invalid value = %d",
4432 roamScanControl);
4433 ret = -EINVAL;
4434 goto exit;
4435 }
4436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4437 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4438
4439 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4440 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004441#ifdef FEATURE_WLAN_OKC
4442 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4443 {
4444 tANI_U8 *value = command;
4445 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4446
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004447 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004448 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004449 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004450 hdd_is_okc_mode_enabled(pHddCtx) &&
4451 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4452 {
4453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004454 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004455 " hence this operation is not permitted!", __func__);
4456 ret = -EPERM;
4457 goto exit;
4458 }
4459
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004460 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4461 value = value + 11;
4462 /* Convert the value from ascii to integer */
4463 ret = kstrtou8(value, 10, &okcMode);
4464 if (ret < 0)
4465 {
4466 /* If the input value is greater than max value of datatype, then also
4467 kstrtou8 fails */
4468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4469 "%s: kstrtou8 failed range [%d - %d]", __func__,
4470 CFG_OKC_FEATURE_ENABLED_MIN,
4471 CFG_OKC_FEATURE_ENABLED_MAX);
4472 ret = -EINVAL;
4473 goto exit;
4474 }
4475
4476 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4477 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4478 {
4479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4480 "Okc mode value %d is out of range"
4481 " (Min: %d Max: %d)", okcMode,
4482 CFG_OKC_FEATURE_ENABLED_MIN,
4483 CFG_OKC_FEATURE_ENABLED_MAX);
4484 ret = -EINVAL;
4485 goto exit;
4486 }
4487
4488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4489 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4490
4491 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4492 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004493#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304494 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004495 {
4496 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4497 char extra[32];
4498 tANI_U8 len = 0;
4499
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004500 len = scnprintf(extra, sizeof(extra), "%s %d",
4501 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304502 len = VOS_MIN(priv_data.total_len, len + 1);
4503 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4505 "%s: failed to copy data to user buffer", __func__);
4506 ret = -EFAULT;
4507 goto exit;
4508 }
4509 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304510#ifdef WLAN_FEATURE_PACKET_FILTERING
4511 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4512 {
4513 tANI_U8 filterType = 0;
4514 tANI_U8 *value = command;
4515
4516 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4517 value = value + 22;
4518
4519 /* Convert the value from ascii to integer */
4520 ret = kstrtou8(value, 10, &filterType);
4521 if (ret < 0)
4522 {
4523 /* If the input value is greater than max value of datatype,
4524 * then also kstrtou8 fails
4525 */
4526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4527 "%s: kstrtou8 failed range ", __func__);
4528 ret = -EINVAL;
4529 goto exit;
4530 }
4531
4532 if (filterType != 0 && filterType != 1)
4533 {
4534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4535 "%s: Accepted Values are 0 and 1 ", __func__);
4536 ret = -EINVAL;
4537 goto exit;
4538 }
4539 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4540 pAdapter->sessionId);
4541 }
4542#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304543 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4544 {
Kiet Lamad161252014-07-22 11:23:32 -07004545 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304546 int ret;
4547
Kiet Lamad161252014-07-22 11:23:32 -07004548 dhcpPhase = command + 11;
4549 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304550 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004552 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304553
4554 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004555
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304556 ret = wlan_hdd_scan_abort(pAdapter);
4557 if (ret < 0)
4558 {
4559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4560 FL("failed to abort existing scan %d"), ret);
4561 }
4562
Kiet Lamad161252014-07-22 11:23:32 -07004563 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4564 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304565 }
Kiet Lamad161252014-07-22 11:23:32 -07004566 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304567 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004569 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304570
4571 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004572
4573 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4574 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304575 }
4576 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004577 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4578 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304579 hddLog(LOG1,
4580 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304581 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004582 }
4583 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4584 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304585 hddLog(LOG1,
4586 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304587 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004588 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304589 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4590 {
4591 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4592 char extra[32];
4593 tANI_U8 len = 0;
4594
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304595 memset(extra, 0, sizeof(extra));
4596 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304597 len = VOS_MIN(priv_data.total_len, len + 1);
4598 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4600 "%s: failed to copy data to user buffer", __func__);
4601 ret = -EFAULT;
4602 goto exit;
4603 }
4604 ret = len;
4605 }
4606 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4607 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304608 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304609 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004610 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4611 {
4612 tANI_U8 filterType = 0;
4613 tANI_U8 *value;
4614 value = command + 9;
4615
4616 /* Convert the value from ascii to integer */
4617 ret = kstrtou8(value, 10, &filterType);
4618 if (ret < 0)
4619 {
4620 /* If the input value is greater than max value of datatype,
4621 * then also kstrtou8 fails
4622 */
4623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4624 "%s: kstrtou8 failed range ", __func__);
4625 ret = -EINVAL;
4626 goto exit;
4627 }
4628 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4629 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4630 {
4631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4632 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4633 " 2-Sink ", __func__);
4634 ret = -EINVAL;
4635 goto exit;
4636 }
4637 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4638 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304639 pScanInfo = &pHddCtx->scan_info;
4640 if (filterType && pScanInfo != NULL &&
4641 pHddCtx->scan_info.mScanPending)
4642 {
4643 /*Miracast Session started. Abort Scan */
4644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4645 "%s, Aborting Scan For Miracast",__func__);
4646 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4647 eCSR_SCAN_ABORT_DEFAULT);
4648 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004649 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304650 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004651 }
Leo Chang614d2072013-08-22 14:59:44 -07004652 else if (strncmp(command, "SETMCRATE", 9) == 0)
4653 {
Leo Chang614d2072013-08-22 14:59:44 -07004654 tANI_U8 *value = command;
4655 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004656 tSirRateUpdateInd *rateUpdate;
4657 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004658
4659 /* Only valid for SAP mode */
4660 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4661 {
4662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4663 "%s: SAP mode is not running", __func__);
4664 ret = -EFAULT;
4665 goto exit;
4666 }
4667
4668 /* Move pointer to ahead of SETMCRATE<delimiter> */
4669 /* input value is in units of hundred kbps */
4670 value = value + 10;
4671 /* Convert the value from ascii to integer, decimal base */
4672 ret = kstrtouint(value, 10, &targetRate);
4673
Leo Chang1f98cbd2013-10-17 15:03:52 -07004674 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4675 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004676 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004677 hddLog(VOS_TRACE_LEVEL_ERROR,
4678 "%s: SETMCRATE indication alloc fail", __func__);
4679 ret = -EFAULT;
4680 goto exit;
4681 }
4682 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4683
4684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4685 "MC Target rate %d", targetRate);
4686 /* Ignore unicast */
4687 rateUpdate->ucastDataRate = -1;
4688 rateUpdate->mcastDataRate24GHz = targetRate;
4689 rateUpdate->mcastDataRate5GHz = targetRate;
4690 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4691 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4692 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4693 if (eHAL_STATUS_SUCCESS != status)
4694 {
4695 hddLog(VOS_TRACE_LEVEL_ERROR,
4696 "%s: SET_MC_RATE failed", __func__);
4697 vos_mem_free(rateUpdate);
4698 ret = -EFAULT;
4699 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004700 }
4701 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304702#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004703 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304704 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004705 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304706 }
4707#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304708#ifdef WLAN_FEATURE_RMC
4709 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4710 (WLAN_HDD_IBSS == pAdapter->device_mode))
4711 {
4712 int i = 0;
4713 tANI_U8 *ibss_ie;
4714 tANI_U32 command_len;
4715 tANI_U8 *value = command;
4716 tHalHandle hHal = pHddCtx->hHal;
4717 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4718 tANI_U32 ibss_ie_length;
4719 tANI_U32 len, present;
4720 tANI_U8 *addIE;
4721 tANI_U8 *addIEData;
4722
4723 hddLog(LOG1,
4724 FL(" received command %s"),((char *) value));
4725 /* validate argument of command */
4726 if (strlen(value) <= 21)
4727 {
4728 hddLog(LOGE,
4729 FL("No arguements in command length %zu"), strlen(value));
4730 ret = -EFAULT;
4731 goto exit;
4732 }
4733
4734 /* moving to arguments of commands */
4735 value = value + 21;
4736 command_len = strlen(value);
4737
4738 /* oui_data can't be less than 3 bytes */
4739 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4740 {
4741 hddLog(LOGE,
4742 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4743 command_len);
4744 ret = -EFAULT;
4745 goto exit;
4746 }
4747 ibss_ie = vos_mem_malloc(command_len);
4748 if (!ibss_ie) {
4749 hddLog(LOGE,
4750 FL("Could not allocate memory for command length %d"),
4751 command_len);
4752 ret = -ENOMEM;
4753 goto exit;
4754 }
4755 vos_mem_zero(ibss_ie, command_len);
4756
4757 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4758 command_len);
4759 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4760 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4761 value, ibss_ie_length);
4762 ret = -EFAULT;
4763 vos_mem_free(ibss_ie);
4764 goto exit;
4765 }
4766
4767 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4768 while (i < ibss_ie_length)
4769 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4770
4771 /* Populate Vendor IE in Beacon */
4772 if ((ccmCfgGetInt(hHal,
4773 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4774 &present)) != eHAL_STATUS_SUCCESS)
4775 {
4776 hddLog(LOGE,
4777 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4778 ret = -EFAULT;
4779 vos_mem_free(ibss_ie);
4780 goto exit;
4781 }
4782
4783 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4784 if (!addIE) {
4785 hddLog(LOGE,
4786 FL("Could not allocate memory for command length %d"),
4787 command_len);
4788 vos_mem_free(ibss_ie);
4789 ret = -ENOMEM;
4790 goto exit;
4791 }
4792 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4793
4794 if (present)
4795 {
4796 if ((wlan_cfgGetStrLen(pMac,
4797 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4798 {
4799 hddLog(LOGE,
4800 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4801 ret = -EFAULT;
4802 vos_mem_free(ibss_ie);
4803 vos_mem_free(addIE);
4804 goto exit;
4805 }
4806
4807 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4808 ((len + ibss_ie_length) <=
4809 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4810 {
4811 if ((ccmCfgGetStr(hHal,
4812 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4813 != eHAL_STATUS_SUCCESS)
4814 {
4815 hddLog(LOGE,
4816 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4817 ret = -EFAULT;
4818 vos_mem_free(ibss_ie);
4819 vos_mem_free(addIE);
4820 goto exit;
4821 }
4822 else
4823 {
4824 /* Curruntly only WPA IE is added before Vendor IE
4825 * so we can blindly place the Vendor IE after WPA
4826 * IE. If no WPA IE found replace all with Vendor IE.
4827 */
4828 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4829 }
4830 }
4831 else
4832 {
4833 hddLog(LOGE,
4834 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4835 len, ibss_ie_length);
4836 ret = -EFAULT;
4837 vos_mem_free(addIE);
4838 vos_mem_free(ibss_ie);
4839 goto exit;
4840 }
4841 }
4842 else {
4843 len = 0;
4844 }
4845
4846 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4847 len += ibss_ie_length;
4848
4849 if (ccmCfgSetStr(hHal,
4850 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4851 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4852 {
4853 hddLog(LOGE,
4854 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4855 ret = -EFAULT;
4856 vos_mem_free(ibss_ie);
4857 vos_mem_free(addIE);
4858 goto exit;
4859 }
4860 vos_mem_free(addIE);
4861 if (ccmCfgSetInt(hHal,
4862 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4863 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4864 {
4865 hddLog(LOGE,
4866 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4867 ret = -EFAULT;
4868 vos_mem_free(ibss_ie);
4869 goto exit;
4870 }
4871
4872 /* Populate Vendor IE in probe resp */
4873 if ((ccmCfgGetInt(hHal,
4874 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
4875 &present)) != eHAL_STATUS_SUCCESS)
4876 {
4877 hddLog(LOGE,
4878 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
4879 ret = -EFAULT;
4880 vos_mem_free(ibss_ie);
4881 goto exit;
4882 }
4883
4884 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
4885 if (!addIEData) {
4886 hddLog(LOGE,
4887 FL("Could not allocate memory for command length %d"),
4888 command_len);
4889 vos_mem_free(ibss_ie);
4890 ret = -ENOMEM;
4891 goto exit;
4892 }
4893 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
4894
4895 if (present) {
4896 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
4897 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
4898 hddLog(LOGE,
4899 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4900 ret = -EFAULT;
4901 vos_mem_free(ibss_ie);
4902 vos_mem_free(addIEData);
4903 goto exit;
4904 }
4905 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
4906 (ibss_ie_length + len) <=
4907 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
4908
4909 if ((ccmCfgGetStr(hHal,
4910 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
4911 != eHAL_STATUS_SUCCESS) {
4912 hddLog(LOGE,
4913 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4914 ret = -EFAULT;
4915 vos_mem_free(ibss_ie);
4916 vos_mem_free(addIEData);
4917 goto exit;
4918 }
4919 else {
4920 /* Curruntly only WPA IE is added before Vendor IE
4921 * so we can blindly place the Vendor IE after WPA
4922 * IE. If no WPA IE found replace all with Vendor IE.
4923 */
4924 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
4925 }
4926 }
4927 else
4928 {
4929 hddLog(LOGE,
4930 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4931 len, ibss_ie_length);
4932 ret = -EFAULT;
4933 vos_mem_free(addIEData);
4934 vos_mem_free(ibss_ie);
4935 goto exit;
4936 }
4937 } /* probe rsp ADD IE present */
4938 else {
4939 /* probe rsp add IE is not present */
4940 len = 0;
4941 }
4942
4943 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
4944 len += ibss_ie_length;
4945
4946 vos_mem_free(ibss_ie);
4947
4948 if (ccmCfgSetStr(hHal,
4949 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4950 (tANI_U8*)(addIEData),
4951 len, NULL,
4952 eANI_BOOLEAN_FALSE)
4953 == eHAL_STATUS_FAILURE) {
4954 hddLog(LOGE,
4955 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4956 ret = -EFAULT;
4957 vos_mem_free(addIEData);
4958 goto exit;
4959 }
4960 vos_mem_free(addIEData);
4961 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
4962 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4963 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4964 {
4965 hddLog(LOGE,
4966 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
4967 ret = -EFAULT;
4968 goto exit;
4969 }
4970 }
4971 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
4972 {
4973 tANI_U8 *value = command;
4974 tANI_U8 ucRmcEnable = 0;
4975 int status;
4976
4977 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
4978 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
4979 {
4980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4981 "Received SETRMCENABLE command in invalid mode %d "
4982 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
4983 pAdapter->device_mode);
4984 ret = -EINVAL;
4985 goto exit;
4986 }
4987
4988 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
4989 if (status)
4990 {
4991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4992 "Invalid SETRMCENABLE command ");
4993 ret = -EINVAL;
4994 goto exit;
4995 }
4996
4997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4998 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
4999
5000 if (TRUE == ucRmcEnable)
5001 {
5002 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5003 pAdapter->sessionId );
5004 }
5005 else if(FALSE == ucRmcEnable)
5006 {
5007 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5008 pAdapter->sessionId );
5009 }
5010 else
5011 {
5012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5013 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5014 ret = -EINVAL;
5015 goto exit;
5016 }
5017
5018 if (VOS_STATUS_SUCCESS != status)
5019 {
5020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5021 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5022 status);
5023 ret = -EINVAL;
5024 goto exit;
5025 }
5026 }
5027 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5028 {
5029 tANI_U8 *value = command;
5030 tANI_U32 uActionPeriod = 0;
5031 int status;
5032
5033 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5034 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5035 {
5036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5037 "Received SETRMC command in invalid mode %d "
5038 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5039 pAdapter->device_mode);
5040 ret = -EINVAL;
5041 goto exit;
5042 }
5043
5044 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5045 if (status)
5046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5048 "Invalid SETRMCACTIONPERIOD command ");
5049 ret = -EINVAL;
5050 goto exit;
5051 }
5052
5053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5054 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5055
5056 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5057 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5058 {
5059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5060 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5061 ret = -EINVAL;
5062 goto exit;
5063 }
5064
5065 }
5066 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5067 {
5068 /* Peer Info All Command */
5069 int status = eHAL_STATUS_SUCCESS;
5070 hdd_station_ctx_t *pHddStaCtx = NULL;
5071 char *extra = NULL;
5072 int idx = 0, length = 0;
5073 v_MACADDR_t *macAddr;
5074 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5075
5076 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5077 {
5078 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5079 }
5080 else
5081 {
5082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5083 "%s: pAdapter is not valid for this device mode",
5084 __func__);
5085 ret = -EINVAL;
5086 goto exit;
5087 }
5088
5089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5090 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5091
5092
5093 /* Handle the command */
5094 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5095 if (VOS_STATUS_SUCCESS == status)
5096 {
5097 /* The variable extra needed to be allocated on the heap since
5098 * amount of memory required to copy the data for 32 devices
5099 * exceeds the size of 1024 bytes of default stack size. On
5100 * 64 bit devices, the default max stack size of 2048 bytes
5101 */
5102 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5103
5104 if (NULL == extra)
5105 {
5106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5107 "%s:kmalloc failed", __func__);
5108 ret = -EINVAL;
5109 goto exit;
5110 }
5111
5112 /* Copy number of stations */
5113 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5114 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5115 numOfBytestoPrint = length;
5116 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5117 {
5118 macAddr =
5119 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5120 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5121 if (NULL != macAddr)
5122 {
5123 txRateMbps =
5124 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5125
5126 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5127 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5128 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5129 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5130 (int)txRateMbps,
5131 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5132 }
5133 else
5134 {
5135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5136 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5137 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5138 }
5139
5140 /*
5141 * VOS_TRACE() macro has limitation of 512 bytes for the print
5142 * buffer. Hence printing the data in two chunks. The first chunk
5143 * will have the data for 16 devices and the second chunk will
5144 * have the rest.
5145 */
5146 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5147 {
5148 numOfBytestoPrint = length;
5149 }
5150 }
5151
5152 /*
5153 * Copy the data back into buffer, if the data to copy is
5154 * morethan 512 bytes than we will split the data and do
5155 * it in two shots
5156 */
5157 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5158 {
5159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5160 "%s: Copy into user data buffer failed ", __func__);
5161 ret = -EFAULT;
5162 kfree(extra);
5163 goto exit;
5164 }
5165 priv_data.buf[numOfBytestoPrint] = '\0';
5166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5167 "%s", priv_data.buf);
5168
5169 if (length > numOfBytestoPrint)
5170 {
5171 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5172 extra + numOfBytestoPrint,
5173 length - numOfBytestoPrint + 1))
5174 {
5175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5176 "%s: Copy into user data buffer failed ", __func__);
5177 ret = -EFAULT;
5178 kfree(extra);
5179 goto exit;
5180 }
5181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5182 "%s", &priv_data.buf[numOfBytestoPrint]);
5183 }
5184
5185 /* Free temporary buffer */
5186 kfree(extra);
5187 }
5188
5189 else
5190 {
5191 /* Command failed, log error */
5192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5193 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5194 __func__, status);
5195 ret = -EINVAL;
5196 goto exit;
5197 }
5198 ret = 0;
5199 }
5200 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5201 {
5202 /* Peer Info <Peer Addr> command */
5203 tANI_U8 *value = command;
5204 VOS_STATUS status;
5205 hdd_station_ctx_t *pHddStaCtx = NULL;
5206 char extra[128] = { 0 };
5207 v_U32_t length = 0;
5208 v_U8_t staIdx = 0;
5209 v_U32_t txRateMbps = 0;
5210 v_MACADDR_t peerMacAddr;
5211
5212 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5213 {
5214 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5215 }
5216 else
5217 {
5218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5219 "%s: pAdapter is not valid for this device mode",
5220 __func__);
5221 ret = -EINVAL;
5222 goto exit;
5223 }
5224
5225 /* if there are no peers, no need to continue with the command */
5226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5227 "%s: Received GETIBSSPEERINFO Command", __func__);
5228
5229 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5230 {
5231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5232 "%s:No IBSS Peers coalesced", __func__);
5233 ret = -EINVAL;
5234 goto exit;
5235 }
5236
5237 /* Parse the incoming command buffer */
5238 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5239 if (VOS_STATUS_SUCCESS != status)
5240 {
5241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5242 "%s: Invalid GETIBSSPEERINFO command", __func__);
5243 ret = -EINVAL;
5244 goto exit;
5245 }
5246
5247 /* Get station index for the peer mac address */
5248 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5249
5250 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5251 {
5252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5253 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5254 ret = -EINVAL;
5255 goto exit;
5256 }
5257
5258 /* Handle the command */
5259 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5260 if (VOS_STATUS_SUCCESS == status)
5261 {
5262 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5263 txRateMbps = (txRate * 500 * 1000)/1000000;
5264
5265 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5266 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5267
5268 /* Copy the data back into buffer */
5269 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5270 {
5271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5272 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5273 __func__);
5274 ret = -EFAULT;
5275 goto exit;
5276 }
5277 }
5278 else
5279 {
5280 /* Command failed, log error */
5281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5282 "%s: GETIBSSPEERINFO command failed with status code %d",
5283 __func__, status);
5284 ret = -EINVAL;
5285 goto exit;
5286 }
5287
5288 /* Success ! */
5289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5290 "%s", priv_data.buf);
5291 ret = 0;
5292 }
5293 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5294 {
5295 tANI_U8 *value = command;
5296 tANI_U32 uRate = 0;
5297 tTxrateinfoflags txFlags = 0;
5298 tSirRateUpdateInd *rateUpdateParams;
5299 int status;
5300
5301 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5302 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5303 {
5304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5305 "Received SETRMCTXRATE command in invalid mode %d "
5306 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5307 pAdapter->device_mode);
5308 ret = -EINVAL;
5309 goto exit;
5310 }
5311
5312 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5313 if (status)
5314 {
5315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5316 "Invalid SETRMCTXRATE command ");
5317 ret = -EINVAL;
5318 goto exit;
5319 }
5320
5321 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5322 if (NULL == rateUpdateParams)
5323 {
5324 ret = -EINVAL;
5325 goto exit;
5326 }
5327
5328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5329 "%s: uRate %d ", __func__, uRate);
5330
5331 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5332
5333 /* -1 implies ignore this param */
5334 rateUpdateParams->ucastDataRate = -1;
5335
5336 /*
5337 * Fill the user specifieed RMC rate param
5338 * and the derived tx flags.
5339 */
5340 rateUpdateParams->rmcDataRate = uRate;
5341 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5342
5343 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5344 }
5345 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5346 {
5347 char *value;
5348 tANI_U8 tx_fail_count = 0;
5349 tANI_U16 pid = 0;
5350
5351 value = command;
5352
5353 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5354
5355 if (0 != ret)
5356 {
5357 hddLog(VOS_TRACE_LEVEL_INFO,
5358 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5359 __func__);
5360 goto exit;
5361 }
5362
5363 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5364 __func__, tx_fail_count, pid);
5365
5366 if (0 == tx_fail_count)
5367 {
5368 // Disable TX Fail Indication
5369 if (eHAL_STATUS_SUCCESS ==
5370 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5371 tx_fail_count,
5372 NULL))
5373 {
5374 cesium_pid = 0;
5375 }
5376 else
5377 {
5378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5379 "%s: failed to disable TX Fail Event ", __func__);
5380 ret = -EINVAL;
5381 }
5382 }
5383 else
5384 {
5385 if (eHAL_STATUS_SUCCESS ==
5386 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5387 tx_fail_count,
5388 (void*)hdd_tx_fail_ind_callback))
5389 {
5390 cesium_pid = pid;
5391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5392 "%s: Registered Cesium pid %u", __func__,
5393 cesium_pid);
5394 }
5395 else
5396 {
5397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5398 "%s: Failed to enable TX Fail Monitoring", __func__);
5399 ret = -EINVAL;
5400 }
5401 }
5402 }
5403
5404#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005405#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005406 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5407 {
5408 tANI_U8 *value = command;
5409 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5410 tANI_U8 numChannels = 0;
5411 eHalStatus status = eHAL_STATUS_SUCCESS;
5412
5413 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5414 if (eHAL_STATUS_SUCCESS != status)
5415 {
5416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5417 "%s: Failed to parse channel list information", __func__);
5418 ret = -EINVAL;
5419 goto exit;
5420 }
5421
5422 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5423 {
5424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5425 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5426 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5427 ret = -EINVAL;
5428 goto exit;
5429 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005430 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005431 ChannelList,
5432 numChannels);
5433 if (eHAL_STATUS_SUCCESS != status)
5434 {
5435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5436 "%s: Failed to update channel list information", __func__);
5437 ret = -EINVAL;
5438 goto exit;
5439 }
5440 }
5441 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5442 {
5443 tANI_U8 *value = command;
5444 char extra[128] = {0};
5445 int len = 0;
5446 tANI_U8 tid = 0;
5447 hdd_station_ctx_t *pHddStaCtx = NULL;
5448 tAniTrafStrmMetrics tsmMetrics;
5449 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5450
5451 /* if not associated, return error */
5452 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5453 {
5454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5455 ret = -EINVAL;
5456 goto exit;
5457 }
5458
5459 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5460 value = value + 12;
5461 /* Convert the value from ascii to integer */
5462 ret = kstrtou8(value, 10, &tid);
5463 if (ret < 0)
5464 {
5465 /* If the input value is greater than max value of datatype, then also
5466 kstrtou8 fails */
5467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5468 "%s: kstrtou8 failed range [%d - %d]", __func__,
5469 TID_MIN_VALUE,
5470 TID_MAX_VALUE);
5471 ret = -EINVAL;
5472 goto exit;
5473 }
5474
5475 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5476 {
5477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5478 "tid value %d is out of range"
5479 " (Min: %d Max: %d)", tid,
5480 TID_MIN_VALUE,
5481 TID_MAX_VALUE);
5482 ret = -EINVAL;
5483 goto exit;
5484 }
5485
5486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5487 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5488
5489 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5490 {
5491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5492 "%s: failed to get tsm stats", __func__);
5493 ret = -EFAULT;
5494 goto exit;
5495 }
5496
5497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5498 "UplinkPktQueueDly(%d)\n"
5499 "UplinkPktQueueDlyHist[0](%d)\n"
5500 "UplinkPktQueueDlyHist[1](%d)\n"
5501 "UplinkPktQueueDlyHist[2](%d)\n"
5502 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305503 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005504 "UplinkPktLoss(%d)\n"
5505 "UplinkPktCount(%d)\n"
5506 "RoamingCount(%d)\n"
5507 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5508 tsmMetrics.UplinkPktQueueDlyHist[0],
5509 tsmMetrics.UplinkPktQueueDlyHist[1],
5510 tsmMetrics.UplinkPktQueueDlyHist[2],
5511 tsmMetrics.UplinkPktQueueDlyHist[3],
5512 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5513 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5514
5515 /* Output TSM stats is of the format
5516 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5517 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005518 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005519 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5520 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5521 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5522 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5523 tsmMetrics.RoamingDly);
5524
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305525 len = VOS_MIN(priv_data.total_len, len + 1);
5526 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5528 "%s: failed to copy data to user buffer", __func__);
5529 ret = -EFAULT;
5530 goto exit;
5531 }
5532 }
5533 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5534 {
5535 tANI_U8 *value = command;
5536 tANI_U8 *cckmIe = NULL;
5537 tANI_U8 cckmIeLen = 0;
5538 eHalStatus status = eHAL_STATUS_SUCCESS;
5539
5540 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5541 if (eHAL_STATUS_SUCCESS != status)
5542 {
5543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5544 "%s: Failed to parse cckm ie data", __func__);
5545 ret = -EINVAL;
5546 goto exit;
5547 }
5548
5549 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5550 {
5551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5552 "%s: CCKM Ie input length is more than max[%d]", __func__,
5553 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005554 vos_mem_free(cckmIe);
5555 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005556 ret = -EINVAL;
5557 goto exit;
5558 }
5559 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005560 vos_mem_free(cckmIe);
5561 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005562 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005563 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5564 {
5565 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005566 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005567 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005568
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005569 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005570 if (eHAL_STATUS_SUCCESS != status)
5571 {
5572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005573 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005574 ret = -EINVAL;
5575 goto exit;
5576 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005577 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5578 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5579 hdd_indicateEseBcnReportNoResults (pAdapter,
5580 eseBcnReq.bcnReq[0].measurementToken,
5581 0x02, //BIT(1) set for measurement done
5582 0); // no BSS
5583 goto exit;
5584 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005585
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005586 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5587 if (eHAL_STATUS_SUCCESS != status)
5588 {
5589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5590 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5591 ret = -EINVAL;
5592 goto exit;
5593 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005594 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005595#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305596 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5597 {
5598 eHalStatus status;
5599 char buf[32], len;
5600 long waitRet;
5601 bcnMissRateContext_t getBcnMissRateCtx;
5602
5603 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5604
5605 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5606 {
5607 hddLog(VOS_TRACE_LEVEL_WARN,
5608 FL("GETBCNMISSRATE: STA is not in connected state"));
5609 ret = -1;
5610 goto exit;
5611 }
5612
5613 init_completion(&(getBcnMissRateCtx.completion));
5614 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5615
5616 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5617 pAdapter->sessionId,
5618 (void *)getBcnMissRateCB,
5619 (void *)(&getBcnMissRateCtx));
5620 if( eHAL_STATUS_SUCCESS != status)
5621 {
5622 hddLog(VOS_TRACE_LEVEL_INFO,
5623 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5624 ret = -EINVAL;
5625 goto exit;
5626 }
5627
5628 waitRet = wait_for_completion_interruptible_timeout
5629 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5630 if(waitRet <= 0)
5631 {
5632 hddLog(VOS_TRACE_LEVEL_ERROR,
5633 FL("failed to wait on bcnMissRateComp %d"), ret);
5634
5635 //Make magic number to zero so that callback is not called.
5636 spin_lock(&hdd_context_lock);
5637 getBcnMissRateCtx.magic = 0x0;
5638 spin_unlock(&hdd_context_lock);
5639 ret = -EINVAL;
5640 goto exit;
5641 }
5642
5643 hddLog(VOS_TRACE_LEVEL_INFO,
5644 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5645
5646 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5647 if (copy_to_user(priv_data.buf, &buf, len + 1))
5648 {
5649 hddLog(VOS_TRACE_LEVEL_ERROR,
5650 "%s: failed to copy data to user buffer", __func__);
5651 ret = -EFAULT;
5652 goto exit;
5653 }
5654 ret = len;
5655 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305656#ifdef FEATURE_WLAN_TDLS
5657 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5658 tANI_U8 *value = command;
5659 int set_value;
5660 /* Move pointer to ahead of TDLSOFFCH*/
5661 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305662 if (!(sscanf(value, "%d", &set_value))) {
5663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5664 FL("No input identified"));
5665 ret = -EINVAL;
5666 goto exit;
5667 }
5668
Atul Mittal87ec2422014-09-24 13:12:50 +05305669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5670 "%s: Tdls offchannel offset:%d",
5671 __func__, set_value);
5672 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5673 if (ret < 0)
5674 {
5675 ret = -EINVAL;
5676 goto exit;
5677 }
5678
5679 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5680 tANI_U8 *value = command;
5681 int set_value;
5682 /* Move pointer to ahead of tdlsoffchnmode*/
5683 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305684 ret = sscanf(value, "%d", &set_value);
5685 if (ret != 1) {
5686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5687 FL("No input identified"));
5688 ret = -EINVAL;
5689 goto exit;
5690 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5692 "%s: Tdls offchannel mode:%d",
5693 __func__, set_value);
5694 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5695 if (ret < 0)
5696 {
5697 ret = -EINVAL;
5698 goto exit;
5699 }
5700 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5701 tANI_U8 *value = command;
5702 int set_value;
5703 /* Move pointer to ahead of TDLSOFFCH*/
5704 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305705 ret = sscanf(value, "%d", &set_value);
5706 if (ret != 1) {
5707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5708 "Wrong value is given for hdd_set_tdls_offchannel");
5709 ret = -EINVAL;
5710 goto exit;
5711 }
5712
Atul Mittal87ec2422014-09-24 13:12:50 +05305713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5714 "%s: Tdls offchannel num: %d",
5715 __func__, set_value);
5716 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5717 if (ret < 0)
5718 {
5719 ret = -EINVAL;
5720 goto exit;
5721 }
5722 }
5723#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305724 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5725 {
5726 eHalStatus status;
5727 char *buf = NULL;
5728 char len;
5729 long waitRet;
5730 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305731 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305732 tANI_U8 *ptr = command;
5733 int stats = *(ptr + 11) - '0';
5734
5735 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5736 if (!IS_FEATURE_FW_STATS_ENABLE)
5737 {
5738 hddLog(VOS_TRACE_LEVEL_INFO,
5739 FL("Get Firmware stats feature not supported"));
5740 ret = -EINVAL;
5741 goto exit;
5742 }
5743
5744 if (FW_STATS_MAX <= stats || 0 >= stats)
5745 {
5746 hddLog(VOS_TRACE_LEVEL_INFO,
5747 FL(" stats %d not supported"),stats);
5748 ret = -EINVAL;
5749 goto exit;
5750 }
5751
5752 init_completion(&(fwStatsCtx.completion));
5753 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5754 fwStatsCtx.pAdapter = pAdapter;
5755 fwStatsRsp->type = 0;
5756 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305757 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305758 if (eHAL_STATUS_SUCCESS != status)
5759 {
5760 hddLog(VOS_TRACE_LEVEL_ERROR,
5761 FL(" fail to post WDA cmd status = %d"), status);
5762 ret = -EINVAL;
5763 goto exit;
5764 }
5765 waitRet = wait_for_completion_timeout
5766 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5767 if (waitRet <= 0)
5768 {
5769 hddLog(VOS_TRACE_LEVEL_ERROR,
5770 FL("failed to wait on GwtFwstats"));
5771 //Make magic number to zero so that callback is not executed.
5772 spin_lock(&hdd_context_lock);
5773 fwStatsCtx.magic = 0x0;
5774 spin_unlock(&hdd_context_lock);
5775 ret = -EINVAL;
5776 goto exit;
5777 }
5778 if (fwStatsRsp->type)
5779 {
5780 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5781 if (!buf)
5782 {
5783 hddLog(VOS_TRACE_LEVEL_ERROR,
5784 FL(" failed to allocate memory"));
5785 ret = -ENOMEM;
5786 goto exit;
5787 }
5788 switch( fwStatsRsp->type )
5789 {
5790 case FW_UBSP_STATS:
5791 {
5792 len = snprintf(buf, FW_STATE_RSP_LEN,
5793 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305794 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5795 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305796 }
5797 break;
5798 default:
5799 {
5800 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5801 ret = -EFAULT;
5802 kfree(buf);
5803 goto exit;
5804 }
5805 }
5806 if (copy_to_user(priv_data.buf, buf, len + 1))
5807 {
5808 hddLog(VOS_TRACE_LEVEL_ERROR,
5809 FL(" failed to copy data to user buffer"));
5810 ret = -EFAULT;
5811 kfree(buf);
5812 goto exit;
5813 }
5814 ret = len;
5815 kfree(buf);
5816 }
5817 else
5818 {
5819 hddLog(VOS_TRACE_LEVEL_ERROR,
5820 FL("failed to fetch the stats"));
5821 ret = -EFAULT;
5822 goto exit;
5823 }
5824
5825 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305826 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5827 {
5828 /*
5829 * this command wld be called by user-space when it detects WLAN
5830 * ON after airplane mode is set. When APM is set, WLAN turns off.
5831 * But it can be turned back on. Otherwise; when APM is turned back
5832 * off, WLAN wld turn back on. So at that point the command is
5833 * expected to come down. 0 means disable, 1 means enable. The
5834 * constraint is removed when parameter 1 is set or different
5835 * country code is set
5836 */
5837 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5838 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305839 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5840 {
5841 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5842 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005843 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305844 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5845 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5846 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305847 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5848 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005849 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 }
5851exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305852 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 if (command)
5854 {
5855 kfree(command);
5856 }
5857 return ret;
5858}
5859
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005860#ifdef CONFIG_COMPAT
5861static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5862{
5863 struct {
5864 compat_uptr_t buf;
5865 int used_len;
5866 int total_len;
5867 } compat_priv_data;
5868 hdd_priv_data_t priv_data;
5869 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005870
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005871 /*
5872 * Note that pAdapter and ifr have already been verified by caller,
5873 * and HDD context has also been validated
5874 */
5875 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
5876 sizeof(compat_priv_data))) {
5877 ret = -EFAULT;
5878 goto exit;
5879 }
5880 priv_data.buf = compat_ptr(compat_priv_data.buf);
5881 priv_data.used_len = compat_priv_data.used_len;
5882 priv_data.total_len = compat_priv_data.total_len;
5883 ret = hdd_driver_command(pAdapter, &priv_data);
5884 exit:
5885 return ret;
5886}
5887#else /* CONFIG_COMPAT */
5888static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5889{
5890 /* will never be invoked */
5891 return 0;
5892}
5893#endif /* CONFIG_COMPAT */
5894
5895static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5896{
5897 hdd_priv_data_t priv_data;
5898 int ret = 0;
5899
5900 /*
5901 * Note that pAdapter and ifr have already been verified by caller,
5902 * and HDD context has also been validated
5903 */
5904 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
5905 ret = -EFAULT;
5906 } else {
5907 ret = hdd_driver_command(pAdapter, &priv_data);
5908 }
5909 return ret;
5910}
5911
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305912int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005913{
5914 hdd_adapter_t *pAdapter;
5915 hdd_context_t *pHddCtx;
5916 int ret;
5917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305918 ENTER();
5919
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005920 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5921 if (NULL == pAdapter) {
5922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5923 "%s: HDD adapter context is Null", __func__);
5924 ret = -ENODEV;
5925 goto exit;
5926 }
5927 if (dev != pAdapter->dev) {
5928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5929 "%s: HDD adapter/dev inconsistency", __func__);
5930 ret = -ENODEV;
5931 goto exit;
5932 }
5933
5934 if ((!ifr) || (!ifr->ifr_data)) {
5935 ret = -EINVAL;
5936 goto exit;
5937 }
5938
5939 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5940 ret = wlan_hdd_validate_context(pHddCtx);
5941 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005942 ret = -EBUSY;
5943 goto exit;
5944 }
5945
5946 switch (cmd) {
5947 case (SIOCDEVPRIVATE + 1):
5948 if (is_compat_task())
5949 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
5950 else
5951 ret = hdd_driver_ioctl(pAdapter, ifr);
5952 break;
5953 default:
5954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
5955 __func__, cmd);
5956 ret = -EINVAL;
5957 break;
5958 }
5959 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305960 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005961 return ret;
5962}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005963
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305964int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5965{
5966 int ret;
5967
5968 vos_ssr_protect(__func__);
5969 ret = __hdd_ioctl(dev, ifr, cmd);
5970 vos_ssr_unprotect(__func__);
5971
5972 return ret;
5973}
5974
Katya Nigame7b69a82015-04-28 15:24:06 +05305975int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5976{
5977 return 0;
5978}
5979
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005980#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005981/**---------------------------------------------------------------------------
5982
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005983 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005984
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005985 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005986 CCXBEACONREQ<space><Number of fields><space><Measurement token>
5987 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
5988 <space>Scan Mode N<space>Meas Duration N
5989 if the Number of bcn req fields (N) does not match with the actual number of fields passed
5990 then take N.
5991 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
5992 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
5993 This function does not take care of removing duplicate channels from the list
5994
5995 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005996 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005997
5998 \return - 0 for success non-zero for failure
5999
6000 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006001static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6002 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006003{
6004 tANI_U8 *inPtr = pValue;
6005 int tempInt = 0;
6006 int j = 0, i = 0, v = 0;
6007 char buf[32];
6008
6009 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6010 /*no argument after the command*/
6011 if (NULL == inPtr)
6012 {
6013 return -EINVAL;
6014 }
6015 /*no space after the command*/
6016 else if (SPACE_ASCII_VALUE != *inPtr)
6017 {
6018 return -EINVAL;
6019 }
6020
6021 /*removing empty spaces*/
6022 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6023
6024 /*no argument followed by spaces*/
6025 if ('\0' == *inPtr) return -EINVAL;
6026
6027 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006028 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006029 if (1 != v) return -EINVAL;
6030
6031 v = kstrtos32(buf, 10, &tempInt);
6032 if ( v < 0) return -EINVAL;
6033
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306034 tempInt = VOS_MIN(tempInt, SIR_ESE_MAX_MEAS_IE_REQS);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006035 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006036
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306037 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6038
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006039
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006040 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006041 {
6042 for (i = 0; i < 4; i++)
6043 {
6044 /*inPtr pointing to the beginning of first space after number of ie fields*/
6045 inPtr = strpbrk( inPtr, " " );
6046 /*no ie data after the number of ie fields argument*/
6047 if (NULL == inPtr) return -EINVAL;
6048
6049 /*removing empty space*/
6050 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6051
6052 /*no ie data after the number of ie fields argument and spaces*/
6053 if ( '\0' == *inPtr ) return -EINVAL;
6054
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006055 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006056 if (1 != v) return -EINVAL;
6057
6058 v = kstrtos32(buf, 10, &tempInt);
6059 if (v < 0) return -EINVAL;
6060
6061 switch (i)
6062 {
6063 case 0: /* Measurement token */
6064 if (tempInt <= 0)
6065 {
6066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6067 "Invalid Measurement Token(%d)", tempInt);
6068 return -EINVAL;
6069 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006070 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006071 break;
6072
6073 case 1: /* Channel number */
6074 if ((tempInt <= 0) ||
6075 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6076 {
6077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6078 "Invalid Channel Number(%d)", tempInt);
6079 return -EINVAL;
6080 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006081 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006082 break;
6083
6084 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006085 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006086 {
6087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6088 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
6089 return -EINVAL;
6090 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006091 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006092 break;
6093
6094 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006095 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6096 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006097 {
6098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6099 "Invalid Measurement Duration(%d)", tempInt);
6100 return -EINVAL;
6101 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006102 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006103 break;
6104 }
6105 }
6106 }
6107
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006108 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006109 {
6110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306111 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006112 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006113 pEseBcnReq->bcnReq[j].measurementToken,
6114 pEseBcnReq->bcnReq[j].channel,
6115 pEseBcnReq->bcnReq[j].scanMode,
6116 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006117 }
6118
6119 return VOS_STATUS_SUCCESS;
6120}
6121
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006122static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6123{
6124 struct statsContext *pStatsContext = NULL;
6125 hdd_adapter_t *pAdapter = NULL;
6126
6127 if (NULL == pContext)
6128 {
6129 hddLog(VOS_TRACE_LEVEL_ERROR,
6130 "%s: Bad param, pContext [%p]",
6131 __func__, pContext);
6132 return;
6133 }
6134
Jeff Johnson72a40512013-12-19 10:14:15 -08006135 /* there is a race condition that exists between this callback
6136 function and the caller since the caller could time out either
6137 before or while this code is executing. we use a spinlock to
6138 serialize these actions */
6139 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006140
6141 pStatsContext = pContext;
6142 pAdapter = pStatsContext->pAdapter;
6143 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6144 {
6145 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006146 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006147 hddLog(VOS_TRACE_LEVEL_WARN,
6148 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6149 __func__, pAdapter, pStatsContext->magic);
6150 return;
6151 }
6152
Jeff Johnson72a40512013-12-19 10:14:15 -08006153 /* context is valid so caller is still waiting */
6154
6155 /* paranoia: invalidate the magic */
6156 pStatsContext->magic = 0;
6157
6158 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006159 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6160 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6161 tsmMetrics.UplinkPktQueueDlyHist,
6162 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6163 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6164 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6165 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6166 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6167 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6168 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6169
Jeff Johnson72a40512013-12-19 10:14:15 -08006170 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006171 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006172
6173 /* serialization is complete */
6174 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006175}
6176
6177
6178
6179static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6180 tAniTrafStrmMetrics* pTsmMetrics)
6181{
6182 hdd_station_ctx_t *pHddStaCtx = NULL;
6183 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006184 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006185 long lrc;
6186 struct statsContext context;
6187 hdd_context_t *pHddCtx = NULL;
6188
6189 if (NULL == pAdapter)
6190 {
6191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6192 return VOS_STATUS_E_FAULT;
6193 }
6194
6195 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6196 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6197
6198 /* we are connected prepare our callback context */
6199 init_completion(&context.completion);
6200 context.pAdapter = pAdapter;
6201 context.magic = STATS_CONTEXT_MAGIC;
6202
6203 /* query tsm stats */
6204 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6205 pHddStaCtx->conn_info.staId[ 0 ],
6206 pHddStaCtx->conn_info.bssId,
6207 &context, pHddCtx->pvosContext, tid);
6208
6209 if (eHAL_STATUS_SUCCESS != hstatus)
6210 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6212 __func__);
6213 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006214 }
6215 else
6216 {
6217 /* request was sent -- wait for the response */
6218 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6219 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006220 if (lrc <= 0)
6221 {
6222 hddLog(VOS_TRACE_LEVEL_ERROR,
6223 "%s: SME %s while retrieving statistics",
6224 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006225 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006226 }
6227 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006228
Jeff Johnson72a40512013-12-19 10:14:15 -08006229 /* either we never sent a request, we sent a request and received a
6230 response or we sent a request and timed out. if we never sent a
6231 request or if we sent a request and got a response, we want to
6232 clear the magic out of paranoia. if we timed out there is a
6233 race condition such that the callback function could be
6234 executing at the same time we are. of primary concern is if the
6235 callback function had already verified the "magic" but had not
6236 yet set the completion variable when a timeout occurred. we
6237 serialize these activities by invalidating the magic while
6238 holding a shared spinlock which will cause us to block if the
6239 callback is currently executing */
6240 spin_lock(&hdd_context_lock);
6241 context.magic = 0;
6242 spin_unlock(&hdd_context_lock);
6243
6244 if (VOS_STATUS_SUCCESS == vstatus)
6245 {
6246 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6247 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6248 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6249 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6250 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6251 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6252 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6253 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6254 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6255 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6256 }
6257 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006258}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006259#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006260
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006261#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006262void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6263{
6264 eCsrBand band = -1;
6265 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6266 switch (band)
6267 {
6268 case eCSR_BAND_ALL:
6269 *pBand = WLAN_HDD_UI_BAND_AUTO;
6270 break;
6271
6272 case eCSR_BAND_24:
6273 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6274 break;
6275
6276 case eCSR_BAND_5G:
6277 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6278 break;
6279
6280 default:
6281 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6282 *pBand = -1;
6283 break;
6284 }
6285}
6286
6287/**---------------------------------------------------------------------------
6288
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006289 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6290
6291 This function parses the send action frame data passed in the format
6292 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6293
Srinivas Girigowda56076852013-08-20 14:00:50 -07006294 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006295 \param - pTargetApBssid Pointer to target Ap bssid
6296 \param - pChannel Pointer to the Target AP channel
6297 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6298 \param - pBuf Pointer to data
6299 \param - pBufLen Pointer to data length
6300
6301 \return - 0 for success non-zero for failure
6302
6303 --------------------------------------------------------------------------*/
6304VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6305 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6306{
6307 tANI_U8 *inPtr = pValue;
6308 tANI_U8 *dataEnd;
6309 int tempInt;
6310 int j = 0;
6311 int i = 0;
6312 int v = 0;
6313 tANI_U8 tempBuf[32];
6314 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006315 /* 12 hexa decimal digits, 5 ':' and '\0' */
6316 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006317
6318 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6319 /*no argument after the command*/
6320 if (NULL == inPtr)
6321 {
6322 return -EINVAL;
6323 }
6324
6325 /*no space after the command*/
6326 else if (SPACE_ASCII_VALUE != *inPtr)
6327 {
6328 return -EINVAL;
6329 }
6330
6331 /*removing empty spaces*/
6332 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6333
6334 /*no argument followed by spaces*/
6335 if ('\0' == *inPtr)
6336 {
6337 return -EINVAL;
6338 }
6339
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006340 v = sscanf(inPtr, "%17s", macAddress);
6341 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006342 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6344 "Invalid MAC address or All hex inputs are not read (%d)", v);
6345 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006346 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006347
6348 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6349 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6350 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6351 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6352 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6353 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006354
6355 /* point to the next argument */
6356 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6357 /*no argument after the command*/
6358 if (NULL == inPtr) return -EINVAL;
6359
6360 /*removing empty spaces*/
6361 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6362
6363 /*no argument followed by spaces*/
6364 if ('\0' == *inPtr)
6365 {
6366 return -EINVAL;
6367 }
6368
6369 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006370 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006371 if (1 != v) return -EINVAL;
6372
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006373 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306374 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306375 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006376
6377 *pChannel = tempInt;
6378
6379 /* point to the next argument */
6380 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6381 /*no argument after the command*/
6382 if (NULL == inPtr) return -EINVAL;
6383 /*removing empty spaces*/
6384 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6385
6386 /*no argument followed by spaces*/
6387 if ('\0' == *inPtr)
6388 {
6389 return -EINVAL;
6390 }
6391
6392 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006393 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006394 if (1 != v) return -EINVAL;
6395
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006396 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006397 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006398
6399 *pDwellTime = tempInt;
6400
6401 /* point to the next argument */
6402 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6403 /*no argument after the command*/
6404 if (NULL == inPtr) return -EINVAL;
6405 /*removing empty spaces*/
6406 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6407
6408 /*no argument followed by spaces*/
6409 if ('\0' == *inPtr)
6410 {
6411 return -EINVAL;
6412 }
6413
6414 /* find the length of data */
6415 dataEnd = inPtr;
6416 while(('\0' != *dataEnd) )
6417 {
6418 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006419 }
Kiet Lambe150c22013-11-21 16:30:32 +05306420 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006421 if ( *pBufLen <= 0) return -EINVAL;
6422
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006423 /* Allocate the number of bytes based on the number of input characters
6424 whether it is even or odd.
6425 if the number of input characters are even, then we need N/2 byte.
6426 if the number of input characters are odd, then we need do (N+1)/2 to
6427 compensate rounding off.
6428 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6429 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6430 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006431 if (NULL == *pBuf)
6432 {
6433 hddLog(VOS_TRACE_LEVEL_FATAL,
6434 "%s: vos_mem_alloc failed ", __func__);
6435 return -EINVAL;
6436 }
6437
6438 /* the buffer received from the upper layer is character buffer,
6439 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6440 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6441 and f0 in 3rd location */
6442 for (i = 0, j = 0; j < *pBufLen; j += 2)
6443 {
Kiet Lambe150c22013-11-21 16:30:32 +05306444 if( j+1 == *pBufLen)
6445 {
6446 tempByte = hdd_parse_hex(inPtr[j]);
6447 }
6448 else
6449 {
6450 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6451 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006452 (*pBuf)[i++] = tempByte;
6453 }
6454 *pBufLen = i;
6455 return VOS_STATUS_SUCCESS;
6456}
6457
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006458/**---------------------------------------------------------------------------
6459
Srinivas Girigowdade697412013-02-14 16:31:48 -08006460 \brief hdd_parse_channellist() - HDD Parse channel list
6461
6462 This function parses the channel list passed in the format
6463 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006464 if the Number of channels (N) does not match with the actual number of channels passed
6465 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6466 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6467 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6468 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006469
6470 \param - pValue Pointer to input channel list
6471 \param - ChannelList Pointer to local output array to record channel list
6472 \param - pNumChannels Pointer to number of roam scan channels
6473
6474 \return - 0 for success non-zero for failure
6475
6476 --------------------------------------------------------------------------*/
6477VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6478{
6479 tANI_U8 *inPtr = pValue;
6480 int tempInt;
6481 int j = 0;
6482 int v = 0;
6483 char buf[32];
6484
6485 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6486 /*no argument after the command*/
6487 if (NULL == inPtr)
6488 {
6489 return -EINVAL;
6490 }
6491
6492 /*no space after the command*/
6493 else if (SPACE_ASCII_VALUE != *inPtr)
6494 {
6495 return -EINVAL;
6496 }
6497
6498 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006499 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006500
6501 /*no argument followed by spaces*/
6502 if ('\0' == *inPtr)
6503 {
6504 return -EINVAL;
6505 }
6506
6507 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006508 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006509 if (1 != v) return -EINVAL;
6510
Srinivas Girigowdade697412013-02-14 16:31:48 -08006511 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006512 if ((v < 0) ||
6513 (tempInt <= 0) ||
6514 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6515 {
6516 return -EINVAL;
6517 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006518
6519 *pNumChannels = tempInt;
6520
6521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6522 "Number of channels are: %d", *pNumChannels);
6523
6524 for (j = 0; j < (*pNumChannels); j++)
6525 {
6526 /*inPtr pointing to the beginning of first space after number of channels*/
6527 inPtr = strpbrk( inPtr, " " );
6528 /*no channel list after the number of channels argument*/
6529 if (NULL == inPtr)
6530 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006531 if (0 != j)
6532 {
6533 *pNumChannels = j;
6534 return VOS_STATUS_SUCCESS;
6535 }
6536 else
6537 {
6538 return -EINVAL;
6539 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006540 }
6541
6542 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006543 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006544
6545 /*no channel list after the number of channels argument and spaces*/
6546 if ( '\0' == *inPtr )
6547 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006548 if (0 != j)
6549 {
6550 *pNumChannels = j;
6551 return VOS_STATUS_SUCCESS;
6552 }
6553 else
6554 {
6555 return -EINVAL;
6556 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006557 }
6558
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006559 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006560 if (1 != v) return -EINVAL;
6561
Srinivas Girigowdade697412013-02-14 16:31:48 -08006562 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006563 if ((v < 0) ||
6564 (tempInt <= 0) ||
6565 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6566 {
6567 return -EINVAL;
6568 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006569 pChannelList[j] = tempInt;
6570
6571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6572 "Channel %d added to preferred channel list",
6573 pChannelList[j] );
6574 }
6575
Srinivas Girigowdade697412013-02-14 16:31:48 -08006576 return VOS_STATUS_SUCCESS;
6577}
6578
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006579
6580/**---------------------------------------------------------------------------
6581
6582 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
6583
6584 This function parses the reasoc command data passed in the format
6585 REASSOC<space><bssid><space><channel>
6586
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006587 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006588 \param - pTargetApBssid Pointer to target Ap bssid
6589 \param - pChannel Pointer to the Target AP channel
6590
6591 \return - 0 for success non-zero for failure
6592
6593 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006594VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
6595 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006596{
6597 tANI_U8 *inPtr = pValue;
6598 int tempInt;
6599 int v = 0;
6600 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006601 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006602 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006603
6604 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6605 /*no argument after the command*/
6606 if (NULL == inPtr)
6607 {
6608 return -EINVAL;
6609 }
6610
6611 /*no space after the command*/
6612 else if (SPACE_ASCII_VALUE != *inPtr)
6613 {
6614 return -EINVAL;
6615 }
6616
6617 /*removing empty spaces*/
6618 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6619
6620 /*no argument followed by spaces*/
6621 if ('\0' == *inPtr)
6622 {
6623 return -EINVAL;
6624 }
6625
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006626 v = sscanf(inPtr, "%17s", macAddress);
6627 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006628 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6630 "Invalid MAC address or All hex inputs are not read (%d)", v);
6631 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006632 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006633
6634 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6635 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6636 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6637 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6638 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6639 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006640
6641 /* point to the next argument */
6642 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6643 /*no argument after the command*/
6644 if (NULL == inPtr) return -EINVAL;
6645
6646 /*removing empty spaces*/
6647 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6648
6649 /*no argument followed by spaces*/
6650 if ('\0' == *inPtr)
6651 {
6652 return -EINVAL;
6653 }
6654
6655 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006656 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006657 if (1 != v) return -EINVAL;
6658
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006659 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006660 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306661 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006662 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6663 {
6664 return -EINVAL;
6665 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006666
6667 *pChannel = tempInt;
6668 return VOS_STATUS_SUCCESS;
6669}
6670
6671#endif
6672
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006673#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006674/**---------------------------------------------------------------------------
6675
6676 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6677
6678 This function parses the SETCCKM IE command
6679 SETCCKMIE<space><ie data>
6680
6681 \param - pValue Pointer to input data
6682 \param - pCckmIe Pointer to output cckm Ie
6683 \param - pCckmIeLen Pointer to output cckm ie length
6684
6685 \return - 0 for success non-zero for failure
6686
6687 --------------------------------------------------------------------------*/
6688VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6689 tANI_U8 *pCckmIeLen)
6690{
6691 tANI_U8 *inPtr = pValue;
6692 tANI_U8 *dataEnd;
6693 int j = 0;
6694 int i = 0;
6695 tANI_U8 tempByte = 0;
6696
6697 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6698 /*no argument after the command*/
6699 if (NULL == inPtr)
6700 {
6701 return -EINVAL;
6702 }
6703
6704 /*no space after the command*/
6705 else if (SPACE_ASCII_VALUE != *inPtr)
6706 {
6707 return -EINVAL;
6708 }
6709
6710 /*removing empty spaces*/
6711 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6712
6713 /*no argument followed by spaces*/
6714 if ('\0' == *inPtr)
6715 {
6716 return -EINVAL;
6717 }
6718
6719 /* find the length of data */
6720 dataEnd = inPtr;
6721 while(('\0' != *dataEnd) )
6722 {
6723 dataEnd++;
6724 ++(*pCckmIeLen);
6725 }
6726 if ( *pCckmIeLen <= 0) return -EINVAL;
6727
6728 /* Allocate the number of bytes based on the number of input characters
6729 whether it is even or odd.
6730 if the number of input characters are even, then we need N/2 byte.
6731 if the number of input characters are odd, then we need do (N+1)/2 to
6732 compensate rounding off.
6733 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6734 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6735 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6736 if (NULL == *pCckmIe)
6737 {
6738 hddLog(VOS_TRACE_LEVEL_FATAL,
6739 "%s: vos_mem_alloc failed ", __func__);
6740 return -EINVAL;
6741 }
6742 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6743 /* the buffer received from the upper layer is character buffer,
6744 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6745 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6746 and f0 in 3rd location */
6747 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6748 {
6749 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6750 (*pCckmIe)[i++] = tempByte;
6751 }
6752 *pCckmIeLen = i;
6753
6754 return VOS_STATUS_SUCCESS;
6755}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006756#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006757
Jeff Johnson295189b2012-06-20 16:38:30 -07006758/**---------------------------------------------------------------------------
6759
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006760 \brief hdd_is_valid_mac_address() - Validate MAC address
6761
6762 This function validates whether the given MAC address is valid or not
6763 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6764 where X is the hexa decimal digit character and separated by ':'
6765 This algorithm works even if MAC address is not separated by ':'
6766
6767 This code checks given input string mac contains exactly 12 hexadecimal digits.
6768 and a separator colon : appears in the input string only after
6769 an even number of hex digits.
6770
6771 \param - pMacAddr pointer to the input MAC address
6772 \return - 1 for valid and 0 for invalid
6773
6774 --------------------------------------------------------------------------*/
6775
6776v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6777{
6778 int xdigit = 0;
6779 int separator = 0;
6780 while (*pMacAddr)
6781 {
6782 if (isxdigit(*pMacAddr))
6783 {
6784 xdigit++;
6785 }
6786 else if (':' == *pMacAddr)
6787 {
6788 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6789 break;
6790
6791 ++separator;
6792 }
6793 else
6794 {
6795 separator = -1;
6796 /* Invalid MAC found */
6797 return 0;
6798 }
6799 ++pMacAddr;
6800 }
6801 return (xdigit == 12 && (separator == 5 || separator == 0));
6802}
6803
6804/**---------------------------------------------------------------------------
6805
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306806 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006807
6808 \param - dev Pointer to net_device structure
6809
6810 \return - 0 for success non-zero for failure
6811
6812 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306813int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006814{
6815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6816 hdd_context_t *pHddCtx;
6817 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6818 VOS_STATUS status;
6819 v_BOOL_t in_standby = TRUE;
6820
6821 if (NULL == pAdapter)
6822 {
6823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306824 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 return -ENODEV;
6826 }
6827
6828 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306829 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6830 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 if (NULL == pHddCtx)
6832 {
6833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006834 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 return -ENODEV;
6836 }
6837
6838 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6839 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6840 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006841 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6842 {
6843 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306844 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006845 in_standby = FALSE;
6846 break;
6847 }
6848 else
6849 {
6850 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6851 pAdapterNode = pNext;
6852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 }
6854
6855 if (TRUE == in_standby)
6856 {
6857 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6858 {
6859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6860 "wlan out of power save", __func__);
6861 return -EINVAL;
6862 }
6863 }
6864
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006865 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6867 {
6868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006869 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 netif_tx_start_all_queues(dev);
6873 }
6874
6875 return 0;
6876}
6877
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306878/**---------------------------------------------------------------------------
6879
6880 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
6881
6882 This is called in response to ifconfig up
6883
6884 \param - dev Pointer to net_device structure
6885
6886 \return - 0 for success non-zero for failure
6887
6888 --------------------------------------------------------------------------*/
6889int hdd_open(struct net_device *dev)
6890{
6891 int ret;
6892
6893 vos_ssr_protect(__func__);
6894 ret = __hdd_open(dev);
6895 vos_ssr_unprotect(__func__);
6896
6897 return ret;
6898}
6899
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306900int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006901{
6902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6903
6904 if(pAdapter == NULL) {
6905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006906 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006907 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006908 }
6909
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 return 0;
6911}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306912
6913int hdd_mon_open (struct net_device *dev)
6914{
6915 int ret;
6916
6917 vos_ssr_protect(__func__);
6918 ret = __hdd_mon_open(dev);
6919 vos_ssr_unprotect(__func__);
6920
6921 return ret;
6922}
6923
Katya Nigame7b69a82015-04-28 15:24:06 +05306924int hdd_mon_stop(struct net_device *dev)
6925{
6926 return 0;
6927}
6928
Jeff Johnson295189b2012-06-20 16:38:30 -07006929/**---------------------------------------------------------------------------
6930
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306931 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07006932
6933 \param - dev Pointer to net_device structure
6934
6935 \return - 0 for success non-zero for failure
6936
6937 --------------------------------------------------------------------------*/
6938
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306939int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006940{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306941 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6943 hdd_context_t *pHddCtx;
6944 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6945 VOS_STATUS status;
6946 v_BOOL_t enter_standby = TRUE;
6947
6948 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 if (NULL == pAdapter)
6950 {
6951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306952 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 return -ENODEV;
6954 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05306955 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306956 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306957
6958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6959 ret = wlan_hdd_validate_context(pHddCtx);
6960 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306962 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 }
6964
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306965 /* Nothing to be done if the interface is not opened */
6966 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
6967 {
6968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6969 "%s: NETDEV Interface is not OPENED", __func__);
6970 return -ENODEV;
6971 }
6972
6973 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006974 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306976
6977 /* Disable TX on the interface, after this hard_start_xmit() will not
6978 * be called on that interface
6979 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306980 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306982
6983 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 netif_carrier_off(pAdapter->dev);
6985
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306986 /* The interface is marked as down for outside world (aka kernel)
6987 * But the driver is pretty much alive inside. The driver needs to
6988 * tear down the existing connection on the netdev (session)
6989 * cleanup the data pipes and wait until the control plane is stabilized
6990 * for this interface. The call also needs to wait until the above
6991 * mentioned actions are completed before returning to the caller.
6992 * Notice that the hdd_stop_adapter is requested not to close the session
6993 * That is intentional to be able to scan if it is a STA/P2P interface
6994 */
6995 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306996#ifdef FEATURE_WLAN_TDLS
6997 mutex_lock(&pHddCtx->tdls_lock);
6998#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306999 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307000 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307001#ifdef FEATURE_WLAN_TDLS
7002 mutex_unlock(&pHddCtx->tdls_lock);
7003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 /* SoftAP ifaces should never go in power save mode
7005 making sure same here. */
7006 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7007 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 )
7010 {
7011 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7013 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 EXIT();
7015 return 0;
7016 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307017 /* Find if any iface is up. If any iface is up then can't put device to
7018 * sleep/power save mode
7019 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7021 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7022 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007023 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7024 {
7025 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307026 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007027 enter_standby = FALSE;
7028 break;
7029 }
7030 else
7031 {
7032 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7033 pAdapterNode = pNext;
7034 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 }
7036
7037 if (TRUE == enter_standby)
7038 {
7039 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7040 "entering standby", __func__);
7041 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7042 {
7043 /*log and return success*/
7044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7045 "wlan in power save", __func__);
7046 }
7047 }
7048
7049 EXIT();
7050 return 0;
7051}
7052
7053/**---------------------------------------------------------------------------
7054
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307055 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007056
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307057 This is called in response to ifconfig down
7058
7059 \param - dev Pointer to net_device structure
7060
7061 \return - 0 for success non-zero for failure
7062-----------------------------------------------------------------------------*/
7063int hdd_stop (struct net_device *dev)
7064{
7065 int ret;
7066
7067 vos_ssr_protect(__func__);
7068 ret = __hdd_stop(dev);
7069 vos_ssr_unprotect(__func__);
7070
7071 return ret;
7072}
7073
7074/**---------------------------------------------------------------------------
7075
7076 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007077
7078 \param - dev Pointer to net_device structure
7079
7080 \return - void
7081
7082 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307083static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007084{
7085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307086 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 ENTER();
7088
7089 do
7090 {
7091 if (NULL == pAdapter)
7092 {
7093 hddLog(VOS_TRACE_LEVEL_FATAL,
7094 "%s: NULL pAdapter", __func__);
7095 break;
7096 }
7097
7098 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7099 {
7100 hddLog(VOS_TRACE_LEVEL_FATAL,
7101 "%s: Invalid magic", __func__);
7102 break;
7103 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7105 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 {
7107 hddLog(VOS_TRACE_LEVEL_FATAL,
7108 "%s: NULL pHddCtx", __func__);
7109 break;
7110 }
7111
7112 if (dev != pAdapter->dev)
7113 {
7114 hddLog(VOS_TRACE_LEVEL_FATAL,
7115 "%s: Invalid device reference", __func__);
7116 /* we haven't validated all cases so let this go for now */
7117 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307118#ifdef FEATURE_WLAN_TDLS
7119 mutex_lock(&pHddCtx->tdls_lock);
7120#endif
c_hpothu002231a2015-02-05 14:58:51 +05307121 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307122#ifdef FEATURE_WLAN_TDLS
7123 mutex_unlock(&pHddCtx->tdls_lock);
7124#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007125
7126 /* after uninit our adapter structure will no longer be valid */
7127 pAdapter->dev = NULL;
7128 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307129 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 } while (0);
7131
7132 EXIT();
7133}
7134
7135/**---------------------------------------------------------------------------
7136
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307137 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7138
7139 This is called during the netdev unregister to uninitialize all data
7140associated with the device
7141
7142 \param - dev Pointer to net_device structure
7143
7144 \return - void
7145
7146 --------------------------------------------------------------------------*/
7147static void hdd_uninit (struct net_device *dev)
7148{
7149 vos_ssr_protect(__func__);
7150 __hdd_uninit(dev);
7151 vos_ssr_unprotect(__func__);
7152}
7153
7154/**---------------------------------------------------------------------------
7155
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 \brief hdd_release_firmware() -
7157
7158 This function calls the release firmware API to free the firmware buffer.
7159
7160 \param - pFileName Pointer to the File Name.
7161 pCtx - Pointer to the adapter .
7162
7163
7164 \return - 0 for success, non zero for failure
7165
7166 --------------------------------------------------------------------------*/
7167
7168VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7169{
7170 VOS_STATUS status = VOS_STATUS_SUCCESS;
7171 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7172 ENTER();
7173
7174
7175 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7176
7177 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7178
7179 if(pHddCtx->fw) {
7180 release_firmware(pHddCtx->fw);
7181 pHddCtx->fw = NULL;
7182 }
7183 else
7184 status = VOS_STATUS_E_FAILURE;
7185 }
7186 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7187 if(pHddCtx->nv) {
7188 release_firmware(pHddCtx->nv);
7189 pHddCtx->nv = NULL;
7190 }
7191 else
7192 status = VOS_STATUS_E_FAILURE;
7193
7194 }
7195
7196 EXIT();
7197 return status;
7198}
7199
7200/**---------------------------------------------------------------------------
7201
7202 \brief hdd_request_firmware() -
7203
7204 This function reads the firmware file using the request firmware
7205 API and returns the the firmware data and the firmware file size.
7206
7207 \param - pfileName - Pointer to the file name.
7208 - pCtx - Pointer to the adapter .
7209 - ppfw_data - Pointer to the pointer of the firmware data.
7210 - pSize - Pointer to the file size.
7211
7212 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7213
7214 --------------------------------------------------------------------------*/
7215
7216
7217VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7218{
7219 int status;
7220 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7221 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7222 ENTER();
7223
7224 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7225
7226 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7227
7228 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7229 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7230 __func__, pfileName);
7231 retval = VOS_STATUS_E_FAILURE;
7232 }
7233
7234 else {
7235 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7236 *pSize = pHddCtx->fw->size;
7237 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7238 __func__, *pSize);
7239 }
7240 }
7241 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7242
7243 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7244
7245 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7246 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7247 __func__, pfileName);
7248 retval = VOS_STATUS_E_FAILURE;
7249 }
7250
7251 else {
7252 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7253 *pSize = pHddCtx->nv->size;
7254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7255 __func__, *pSize);
7256 }
7257 }
7258
7259 EXIT();
7260 return retval;
7261}
7262/**---------------------------------------------------------------------------
7263 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7264
7265 This is the function invoked by SME to inform the result of a full power
7266 request issued by HDD
7267
7268 \param - callbackcontext - Pointer to cookie
7269 status - result of request
7270
7271 \return - None
7272
7273--------------------------------------------------------------------------*/
7274void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7275{
7276 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7277
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007278 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 if(&pHddCtx->full_pwr_comp_var)
7280 {
7281 complete(&pHddCtx->full_pwr_comp_var);
7282 }
7283}
7284
Abhishek Singh00b71972016-01-07 10:51:04 +05307285#ifdef WLAN_FEATURE_RMC
7286static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7287{
7288 int payload_len;
7289 struct sk_buff *skb;
7290 struct nlmsghdr *nlh;
7291 v_U8_t *data;
7292
7293 payload_len = ETH_ALEN;
7294
7295 if (0 == cesium_pid)
7296 {
7297 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7298 __func__);
7299 return;
7300 }
7301
7302 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7303 {
7304 hddLog(VOS_TRACE_LEVEL_ERROR,
7305 "%s: nlmsg_new() failed for msg size[%d]",
7306 __func__, NLMSG_SPACE(payload_len));
7307 return;
7308 }
7309
7310 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7311
7312 if (NULL == nlh)
7313 {
7314 hddLog(VOS_TRACE_LEVEL_ERROR,
7315 "%s: nlmsg_put() failed for msg size[%d]",
7316 __func__, NLMSG_SPACE(payload_len));
7317
7318 kfree_skb(skb);
7319 return;
7320 }
7321
7322 data = nlmsg_data(nlh);
7323 memcpy(data, MacAddr, ETH_ALEN);
7324
7325 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7326 {
7327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7328 __func__, NLMSG_SPACE(payload_len));
7329 }
7330
7331 return;
7332}
7333
7334/**---------------------------------------------------------------------------
7335 \brief hdd_ParseuserParams - return a pointer to the next argument
7336
7337 \return - status
7338
7339--------------------------------------------------------------------------*/
7340static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7341{
7342 tANI_U8 *pVal;
7343
7344 pVal = strchr(pValue, ' ');
7345
7346 if (NULL == pVal)
7347 {
7348 /* no argument remains */
7349 return -EINVAL;
7350 }
7351 else if (SPACE_ASCII_VALUE != *pVal)
7352 {
7353 /* no space after the current argument */
7354 return -EINVAL;
7355 }
7356
7357 pVal++;
7358
7359 /* remove empty spaces */
7360 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7361 {
7362 pVal++;
7363 }
7364
7365 /* no argument followed by spaces */
7366 if ('\0' == *pVal)
7367 {
7368 return -EINVAL;
7369 }
7370
7371 *ppArg = pVal;
7372
7373 return 0;
7374}
7375
7376/**----------------------------------------------------------------------------
7377 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7378
7379 \return - status
7380
7381------------------------------------------------------------------------------*/
7382static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7383 tANI_U8 *tx_fail_count,
7384 tANI_U16 *pid)
7385{
7386 tANI_U8 *param = NULL;
7387 int ret;
7388
7389 ret = hdd_ParseUserParams(pValue, &param);
7390
7391 if (0 == ret && NULL != param)
7392 {
7393 if (1 != sscanf(param, "%hhu", tx_fail_count))
7394 {
7395 ret = -EINVAL;
7396 goto done;
7397 }
7398 }
7399 else
7400 {
7401 goto done;
7402 }
7403
7404 if (0 == *tx_fail_count)
7405 {
7406 *pid = 0;
7407 goto done;
7408 }
7409
7410 pValue = param;
7411 pValue++;
7412
7413 ret = hdd_ParseUserParams(pValue, &param);
7414
7415 if (0 == ret)
7416 {
7417 if (1 != sscanf(param, "%hu", pid))
7418 {
7419 ret = -EINVAL;
7420 goto done;
7421 }
7422 }
7423 else
7424 {
7425 goto done;
7426 }
7427
7428done:
7429 return ret;
7430}
7431
7432static int hdd_open_cesium_nl_sock()
7433{
7434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7435 struct netlink_kernel_cfg cfg = {
7436 .groups = WLAN_NLINK_MCAST_GRP_ID,
7437 .input = NULL
7438 };
7439#endif
7440 int ret = 0;
7441
7442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7443 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7444#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7445 THIS_MODULE,
7446#endif
7447 &cfg);
7448#else
7449 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7450 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7451#endif
7452
7453 if (cesium_nl_srv_sock == NULL)
7454 {
7455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7456 "NLINK: cesium netlink_kernel_create failed");
7457 ret = -ECONNREFUSED;
7458 }
7459
7460 return ret;
7461}
7462
7463static void hdd_close_cesium_nl_sock()
7464{
7465 if (NULL != cesium_nl_srv_sock)
7466 {
7467 netlink_kernel_release(cesium_nl_srv_sock);
7468 cesium_nl_srv_sock = NULL;
7469 }
7470}
7471#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007472/**---------------------------------------------------------------------------
7473
7474 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7475
7476 This is the function invoked by SME to inform the result of BMPS
7477 request issued by HDD
7478
7479 \param - callbackcontext - Pointer to cookie
7480 status - result of request
7481
7482 \return - None
7483
7484--------------------------------------------------------------------------*/
7485void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7486{
7487
7488 struct completion *completion_var = (struct completion*) callbackContext;
7489
Arif Hussain6d2a3322013-11-17 19:50:10 -08007490 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 if(completion_var != NULL)
7492 {
7493 complete(completion_var);
7494 }
7495}
7496
7497/**---------------------------------------------------------------------------
7498
7499 \brief hdd_get_cfg_file_size() -
7500
7501 This function reads the configuration file using the request firmware
7502 API and returns the configuration file size.
7503
7504 \param - pCtx - Pointer to the adapter .
7505 - pFileName - Pointer to the file name.
7506 - pBufSize - Pointer to the buffer size.
7507
7508 \return - 0 for success, non zero for failure
7509
7510 --------------------------------------------------------------------------*/
7511
7512VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7513{
7514 int status;
7515 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7516
7517 ENTER();
7518
7519 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7520
7521 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7522 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7523 status = VOS_STATUS_E_FAILURE;
7524 }
7525 else {
7526 *pBufSize = pHddCtx->fw->size;
7527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7528 release_firmware(pHddCtx->fw);
7529 pHddCtx->fw = NULL;
7530 }
7531
7532 EXIT();
7533 return VOS_STATUS_SUCCESS;
7534}
7535
7536/**---------------------------------------------------------------------------
7537
7538 \brief hdd_read_cfg_file() -
7539
7540 This function reads the configuration file using the request firmware
7541 API and returns the cfg data and the buffer size of the configuration file.
7542
7543 \param - pCtx - Pointer to the adapter .
7544 - pFileName - Pointer to the file name.
7545 - pBuffer - Pointer to the data buffer.
7546 - pBufSize - Pointer to the buffer size.
7547
7548 \return - 0 for success, non zero for failure
7549
7550 --------------------------------------------------------------------------*/
7551
7552VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7553 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7554{
7555 int status;
7556 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7557
7558 ENTER();
7559
7560 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7561
7562 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7564 return VOS_STATUS_E_FAILURE;
7565 }
7566 else {
7567 if(*pBufSize != pHddCtx->fw->size) {
7568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7569 "file size", __func__);
7570 release_firmware(pHddCtx->fw);
7571 pHddCtx->fw = NULL;
7572 return VOS_STATUS_E_FAILURE;
7573 }
7574 else {
7575 if(pBuffer) {
7576 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7577 }
7578 release_firmware(pHddCtx->fw);
7579 pHddCtx->fw = NULL;
7580 }
7581 }
7582
7583 EXIT();
7584
7585 return VOS_STATUS_SUCCESS;
7586}
7587
7588/**---------------------------------------------------------------------------
7589
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307590 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007591
7592 This function sets the user specified mac address using
7593 the command ifconfig wlanX hw ether <mac adress>.
7594
7595 \param - dev - Pointer to the net device.
7596 - addr - Pointer to the sockaddr.
7597 \return - 0 for success, non zero for failure
7598
7599 --------------------------------------------------------------------------*/
7600
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307601static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007602{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307603 hdd_adapter_t *pAdapter;
7604 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 struct sockaddr *psta_mac_addr = addr;
7606 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307607 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007608
7609 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307610 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7611 if (NULL == pAdapter)
7612 {
7613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7614 "%s: Adapter is NULL",__func__);
7615 return -EINVAL;
7616 }
7617 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7618 ret = wlan_hdd_validate_context(pHddCtx);
7619 if (0 != ret)
7620 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307621 return ret;
7622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007623
7624 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7626
7627 EXIT();
7628 return halStatus;
7629}
7630
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307631/**---------------------------------------------------------------------------
7632
7633 \brief hdd_set_mac_address() -
7634
7635 Wrapper function to protect __hdd_set_mac_address() function from ssr
7636
7637 \param - dev - Pointer to the net device.
7638 - addr - Pointer to the sockaddr.
7639 \return - 0 for success, non zero for failure
7640
7641 --------------------------------------------------------------------------*/
7642static int hdd_set_mac_address(struct net_device *dev, void *addr)
7643{
7644 int ret;
7645
7646 vos_ssr_protect(__func__);
7647 ret = __hdd_set_mac_address(dev, addr);
7648 vos_ssr_unprotect(__func__);
7649
7650 return ret;
7651}
7652
Jeff Johnson295189b2012-06-20 16:38:30 -07007653tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7654{
7655 int i;
7656 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7657 {
Abhishek Singheb183782014-02-06 13:37:21 +05307658 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 break;
7660 }
7661
7662 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7663 return NULL;
7664
7665 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7666 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7667}
7668
7669void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7670{
7671 int i;
7672 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7673 {
7674 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7675 {
7676 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7677 break;
7678 }
7679 }
7680 return;
7681}
7682
7683#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7684 static struct net_device_ops wlan_drv_ops = {
7685 .ndo_open = hdd_open,
7686 .ndo_stop = hdd_stop,
7687 .ndo_uninit = hdd_uninit,
7688 .ndo_start_xmit = hdd_hard_start_xmit,
7689 .ndo_tx_timeout = hdd_tx_timeout,
7690 .ndo_get_stats = hdd_stats,
7691 .ndo_do_ioctl = hdd_ioctl,
7692 .ndo_set_mac_address = hdd_set_mac_address,
7693 .ndo_select_queue = hdd_select_queue,
7694#ifdef WLAN_FEATURE_PACKET_FILTERING
7695#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7696 .ndo_set_rx_mode = hdd_set_multicast_list,
7697#else
7698 .ndo_set_multicast_list = hdd_set_multicast_list,
7699#endif //LINUX_VERSION_CODE
7700#endif
7701 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 static struct net_device_ops wlan_mon_drv_ops = {
7703 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307704 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 .ndo_uninit = hdd_uninit,
7706 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7707 .ndo_tx_timeout = hdd_tx_timeout,
7708 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307709 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 .ndo_set_mac_address = hdd_set_mac_address,
7711 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307712
Jeff Johnson295189b2012-06-20 16:38:30 -07007713#endif
7714
7715void hdd_set_station_ops( struct net_device *pWlanDev )
7716{
7717#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 pWlanDev->netdev_ops = &wlan_drv_ops;
7719#else
7720 pWlanDev->open = hdd_open;
7721 pWlanDev->stop = hdd_stop;
7722 pWlanDev->uninit = hdd_uninit;
7723 pWlanDev->hard_start_xmit = NULL;
7724 pWlanDev->tx_timeout = hdd_tx_timeout;
7725 pWlanDev->get_stats = hdd_stats;
7726 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 pWlanDev->set_mac_address = hdd_set_mac_address;
7728#endif
7729}
7730
Katya Nigam1fd24402015-02-16 14:52:19 +05307731void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7732{
7733 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7734 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7735 #else
7736 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7737 #endif
7738}
7739
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007740static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007741{
7742 struct net_device *pWlanDev = NULL;
7743 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 /*
7745 * cfg80211 initialization and registration....
7746 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307747 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7749 NET_NAME_UNKNOWN,
7750#endif
7751 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 if(pWlanDev != NULL)
7753 {
7754
7755 //Save the pointer to the net_device in the HDD adapter
7756 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7757
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7759
7760 pAdapter->dev = pWlanDev;
7761 pAdapter->pHddCtx = pHddCtx;
7762 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307763 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007764
Rajeev79dbe4c2013-10-05 11:03:42 +05307765#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307766 pAdapter->pBatchScanRsp = NULL;
7767 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007768 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007769 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307770 mutex_init(&pAdapter->hdd_batch_scan_lock);
7771#endif
7772
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 pAdapter->isLinkUpSvcNeeded = FALSE;
7774 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7775 //Init the net_device structure
7776 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7777
7778 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7779 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7780 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7781 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7782
7783 hdd_set_station_ops( pAdapter->dev );
7784
7785 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007786 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7787 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7788 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 /* set pWlanDev's parent to underlying device */
7790 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007791
7792 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 }
7794
7795 return pAdapter;
7796}
7797
7798VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7799{
7800 struct net_device *pWlanDev = pAdapter->dev;
7801 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7802 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7803 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7804
7805 if( rtnl_lock_held )
7806 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007807 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7809 {
7810 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7811 return VOS_STATUS_E_FAILURE;
7812 }
7813 }
7814 if (register_netdevice(pWlanDev))
7815 {
7816 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7817 return VOS_STATUS_E_FAILURE;
7818 }
7819 }
7820 else
7821 {
7822 if(register_netdev(pWlanDev))
7823 {
7824 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7825 return VOS_STATUS_E_FAILURE;
7826 }
7827 }
7828 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7829
7830 return VOS_STATUS_SUCCESS;
7831}
7832
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007833static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007834{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007835 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007836
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007837 if (NULL == pAdapter)
7838 {
7839 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7840 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007842
7843 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7844 {
7845 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7846 return eHAL_STATUS_NOT_INITIALIZED;
7847 }
7848
7849 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7850
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007851#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007852 /* need to make sure all of our scheduled work has completed.
7853 * This callback is called from MC thread context, so it is safe to
7854 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007855 *
7856 * Even though this is called from MC thread context, if there is a faulty
7857 * work item in the system, that can hang this call forever. So flushing
7858 * this global work queue is not safe; and now we make sure that
7859 * individual work queues are stopped correctly. But the cancel work queue
7860 * is a GPL only API, so the proprietary version of the driver would still
7861 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007862 */
7863 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007864#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007865
7866 /* We can be blocked while waiting for scheduled work to be
7867 * flushed, and the adapter structure can potentially be freed, in
7868 * which case the magic will have been reset. So make sure the
7869 * magic is still good, and hence the adapter structure is still
7870 * valid, before signaling completion */
7871 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
7872 {
7873 complete(&pAdapter->session_close_comp_var);
7874 }
7875
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 return eHAL_STATUS_SUCCESS;
7877}
Manjeet Singh47ee8472016-04-11 11:57:18 +05307878/**
7879 * hdd_close_tx_queues() - close tx queues
7880 * @hdd_ctx: hdd global context
7881 *
7882 * Return: None
7883 */
7884static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
7885{
7886 VOS_STATUS status;
7887 hdd_adapter_t *adapter;
7888 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
7889 /* Not validating hdd_ctx as it's already done by the caller */
7890 ENTER();
7891 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
7892 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
7893 adapter = adapter_node->pAdapter;
7894 if (adapter && adapter->dev) {
7895 netif_tx_disable (adapter->dev);
7896 netif_carrier_off(adapter->dev);
7897 }
7898 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
7899 &next_adapter);
7900 adapter_node = next_adapter;
7901 }
7902 EXIT();
7903}
Jeff Johnson295189b2012-06-20 16:38:30 -07007904
7905VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
7906{
7907 struct net_device *pWlanDev = pAdapter->dev;
7908 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7909 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7910 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7911 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307912 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007913
Nirav Shah7e3c8132015-06-22 23:51:42 +05307914 spin_lock_init( &pAdapter->sta_hash_lock);
7915 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
7916
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07007918 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 //Open a SME session for future operation
7920 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07007921 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7923 {
7924 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007925 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 halStatus, halStatus );
7927 status = VOS_STATUS_E_FAILURE;
7928 goto error_sme_open;
7929 }
7930
7931 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05307932 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007933 &pAdapter->session_open_comp_var,
7934 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307935 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 {
7937 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307938 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 status = VOS_STATUS_E_FAILURE;
7940 goto error_sme_open;
7941 }
7942
7943 // Register wireless extensions
7944 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
7945 {
7946 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007947 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 halStatus, halStatus );
7949 status = VOS_STATUS_E_FAILURE;
7950 goto error_register_wext;
7951 }
Katya Nigam1fd24402015-02-16 14:52:19 +05307952
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05307954 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7955 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
7956 #else
7957 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
7958 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007959
7960 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05307961 hddLog(VOS_TRACE_LEVEL_INFO,
7962 "%s: Set HDD connState to eConnectionState_NotConnected",
7963 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7965
7966 //Set the default operation channel
7967 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
7968
7969 /* Make the default Auth Type as OPEN*/
7970 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
7971
7972 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
7973 {
7974 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007975 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 status, status );
7977 goto error_init_txrx;
7978 }
7979
7980 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
7981
7982 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
7983 {
7984 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007985 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 status, status );
7987 goto error_wmm_init;
7988 }
7989
7990 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7991
7992 return VOS_STATUS_SUCCESS;
7993
7994error_wmm_init:
7995 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
7996 hdd_deinit_tx_rx(pAdapter);
7997error_init_txrx:
7998 hdd_UnregisterWext(pWlanDev);
7999error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008000 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 {
8002 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008003 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308004 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008005 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308007 unsigned long rc;
8008
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308010 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008012 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308013 if (rc <= 0)
8014 hddLog(VOS_TRACE_LEVEL_ERROR,
8015 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 }
8017}
8018error_sme_open:
8019 return status;
8020}
8021
Jeff Johnson295189b2012-06-20 16:38:30 -07008022void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8023{
8024 hdd_cfg80211_state_t *cfgState;
8025
8026 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8027
8028 if( NULL != cfgState->buf )
8029 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308030 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8032 rc = wait_for_completion_interruptible_timeout(
8033 &pAdapter->tx_action_cnf_event,
8034 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308035 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8038 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8039 , __func__, rc);
8040
8041 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8042 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 }
8044 }
8045 return;
8046}
Jeff Johnson295189b2012-06-20 16:38:30 -07008047
c_hpothu002231a2015-02-05 14:58:51 +05308048void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008049{
8050 ENTER();
8051 switch ( pAdapter->device_mode )
8052 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308053 case WLAN_HDD_IBSS:
8054 {
8055 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8056 {
8057 hdd_ibss_deinit_tx_rx( pAdapter );
8058 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8059 }
8060 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 case WLAN_HDD_INFRA_STATION:
8062 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008063 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 {
8065 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8066 {
8067 hdd_deinit_tx_rx( pAdapter );
8068 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8069 }
8070
8071 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8072 {
8073 hdd_wmm_adapter_close( pAdapter );
8074 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8075 }
8076
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 break;
8079 }
8080
8081 case WLAN_HDD_SOFTAP:
8082 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308084
8085 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8086 {
8087 hdd_wmm_adapter_close( pAdapter );
8088 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8089 }
8090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008092
c_hpothu002231a2015-02-05 14:58:51 +05308093 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 break;
8096 }
8097
8098 case WLAN_HDD_MONITOR:
8099 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8101 {
8102 hdd_deinit_tx_rx( pAdapter );
8103 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 break;
8106 }
8107
8108
8109 default:
8110 break;
8111 }
8112
8113 EXIT();
8114}
8115
8116void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8117{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008118 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308119
8120 ENTER();
8121 if (NULL == pAdapter)
8122 {
8123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8124 "%s: HDD adapter is Null", __func__);
8125 return;
8126 }
8127
8128 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008129
Rajeev79dbe4c2013-10-05 11:03:42 +05308130#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308131 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8132 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008133 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308134 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8135 )
8136 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008137 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308138 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008139 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8140 {
8141 hdd_deinit_batch_scan(pAdapter);
8142 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308143 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008144 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308145#endif
8146
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8148 if( rtnl_held )
8149 {
8150 unregister_netdevice(pWlanDev);
8151 }
8152 else
8153 {
8154 unregister_netdev(pWlanDev);
8155 }
8156 // note that the pAdapter is no longer valid at this point
8157 // since the memory has been reclaimed
8158 }
8159
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308160 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008161}
8162
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008163void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8164{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308165 VOS_STATUS status;
8166 hdd_adapter_t *pAdapter = NULL;
8167 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008168
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308169 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008170
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308171 /*loop through all adapters.*/
8172 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008173 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308174 pAdapter = pAdapterNode->pAdapter;
8175 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8176 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008177
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308178 { // we skip this registration for modes other than STA and P2P client modes.
8179 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8180 pAdapterNode = pNext;
8181 continue;
8182 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008183
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308184 //Apply Dynamic DTIM For P2P
8185 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8186 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8187 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8188 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8189 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8190 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8191 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8192 (eConnectionState_Associated ==
8193 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8194 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8195 {
8196 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008197
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308198 powerRequest.uIgnoreDTIM = 1;
8199 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8200
8201 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8202 {
8203 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8204 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8205 }
8206 else
8207 {
8208 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8209 }
8210
8211 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8212 * specified during Enter/Exit BMPS when LCD off*/
8213 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8214 NULL, eANI_BOOLEAN_FALSE);
8215 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8216 NULL, eANI_BOOLEAN_FALSE);
8217
8218 /* switch to the DTIM specified in cfg.ini */
8219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308220 "Switch to DTIM %d Listen interval %d",
8221 powerRequest.uDTIMPeriod,
8222 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308223 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8224 break;
8225
8226 }
8227
8228 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8229 pAdapterNode = pNext;
8230 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008231}
8232
8233void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8234{
8235 /*Switch back to DTIM 1*/
8236 tSirSetPowerParamsReq powerRequest = { 0 };
8237
8238 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8239 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008240 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008241
8242 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8243 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8244 NULL, eANI_BOOLEAN_FALSE);
8245 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8246 NULL, eANI_BOOLEAN_FALSE);
8247
8248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8249 "Switch to DTIM%d",powerRequest.uListenInterval);
8250 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8251
8252}
8253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8255{
8256 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308257 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8258 {
8259 hddLog( LOGE, FL("Wlan Unload in progress"));
8260 return VOS_STATUS_E_PERM;
8261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8263 {
8264 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8265 }
8266
8267 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8268 {
8269 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8270 }
8271
8272 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8273 {
8274 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8275 }
8276
8277 return status;
8278}
8279
8280VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8281{
8282 hdd_adapter_t *pAdapter = NULL;
8283 eHalStatus halStatus;
8284 VOS_STATUS status = VOS_STATUS_E_INVAL;
8285 v_BOOL_t disableBmps = FALSE;
8286 v_BOOL_t disableImps = FALSE;
8287
8288 switch(session_type)
8289 {
8290 case WLAN_HDD_INFRA_STATION:
8291 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 case WLAN_HDD_P2P_CLIENT:
8293 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008294 //Exit BMPS -> Is Sta/P2P Client is already connected
8295 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8296 if((NULL != pAdapter)&&
8297 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8298 {
8299 disableBmps = TRUE;
8300 }
8301
8302 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8303 if((NULL != pAdapter)&&
8304 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8305 {
8306 disableBmps = TRUE;
8307 }
8308
8309 //Exit both Bmps and Imps incase of Go/SAP Mode
8310 if((WLAN_HDD_SOFTAP == session_type) ||
8311 (WLAN_HDD_P2P_GO == session_type))
8312 {
8313 disableBmps = TRUE;
8314 disableImps = TRUE;
8315 }
8316
8317 if(TRUE == disableImps)
8318 {
8319 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8320 {
8321 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8322 }
8323 }
8324
8325 if(TRUE == disableBmps)
8326 {
8327 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8328 {
8329 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8330
8331 if(eHAL_STATUS_SUCCESS != halStatus)
8332 {
8333 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008334 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 VOS_ASSERT(0);
8336 return status;
8337 }
8338 }
8339
8340 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8341 {
8342 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8343
8344 if(eHAL_STATUS_SUCCESS != halStatus)
8345 {
8346 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008347 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 VOS_ASSERT(0);
8349 return status;
8350 }
8351 }
8352 }
8353
8354 if((TRUE == disableBmps) ||
8355 (TRUE == disableImps))
8356 {
8357 /* Now, get the chip into Full Power now */
8358 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8359 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8360 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8361
8362 if(halStatus != eHAL_STATUS_SUCCESS)
8363 {
8364 if(halStatus == eHAL_STATUS_PMC_PENDING)
8365 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308366 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 ret = wait_for_completion_interruptible_timeout(
8369 &pHddCtx->full_pwr_comp_var,
8370 msecs_to_jiffies(1000));
8371 if (ret <= 0)
8372 {
8373 hddLog(VOS_TRACE_LEVEL_ERROR,
8374 "%s: wait on full_pwr_comp_var failed %ld",
8375 __func__, ret);
8376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 }
8378 else
8379 {
8380 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008381 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 VOS_ASSERT(0);
8383 return status;
8384 }
8385 }
8386
8387 status = VOS_STATUS_SUCCESS;
8388 }
8389
8390 break;
8391 }
8392 return status;
8393}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308394
8395void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8396{
8397 if (magic == NULL || cmpVar == NULL) {
8398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8399 FL("invalid arguments %p %p"), magic, cmpVar);
8400 return;
8401 }
8402 if (*magic != MON_MODE_MSG_MAGIC) {
8403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8404 FL("maic: %x"), *magic);
8405 return;
8406 }
8407
8408 complete(cmpVar);
8409 return;
8410}
8411
Katya Nigame7b69a82015-04-28 15:24:06 +05308412void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8413 {
8414 hdd_mon_ctx_t *pMonCtx = NULL;
8415 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8416
8417 pMonCtx->state = 0;
8418 pMonCtx->ChannelNo = 1;
8419 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308420 pMonCtx->crcCheckEnabled = 1;
8421 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8422 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308423 pMonCtx->numOfMacFilters = 0;
8424 }
8425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426
8427hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008428 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 tANI_U8 rtnl_held )
8430{
8431 hdd_adapter_t *pAdapter = NULL;
8432 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8433 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8434 VOS_STATUS exitbmpsStatus;
8435
Arif Hussain6d2a3322013-11-17 19:50:10 -08008436 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008437
Nirav Shah436658f2014-02-28 17:05:45 +05308438 if(macAddr == NULL)
8439 {
8440 /* Not received valid macAddr */
8441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8442 "%s:Unable to add virtual intf: Not able to get"
8443 "valid mac address",__func__);
8444 return NULL;
8445 }
8446
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 //Disable BMPS incase of Concurrency
8448 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8449
8450 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8451 {
8452 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308453 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 VOS_ASSERT(0);
8455 return NULL;
8456 }
8457
8458 switch(session_type)
8459 {
8460 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008462 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 {
8464 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8465
8466 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308467 {
8468 hddLog(VOS_TRACE_LEVEL_FATAL,
8469 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308471 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008472
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308473#ifdef FEATURE_WLAN_TDLS
8474 /* A Mutex Lock is introduced while changing/initializing the mode to
8475 * protect the concurrent access for the Adapters by TDLS module.
8476 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308477 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308478#endif
8479
Jeff Johnsone7245742012-09-05 17:12:55 -07008480 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8481 NL80211_IFTYPE_P2P_CLIENT:
8482 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008483
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308485#ifdef FEATURE_WLAN_TDLS
8486 mutex_unlock(&pHddCtx->tdls_lock);
8487#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308488
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308489 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308490 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 if( VOS_STATUS_SUCCESS != status )
8492 goto err_free_netdev;
8493
8494 status = hdd_register_interface( pAdapter, rtnl_held );
8495 if( VOS_STATUS_SUCCESS != status )
8496 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308497#ifdef FEATURE_WLAN_TDLS
8498 mutex_lock(&pHddCtx->tdls_lock);
8499#endif
c_hpothu002231a2015-02-05 14:58:51 +05308500 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308501#ifdef FEATURE_WLAN_TDLS
8502 mutex_unlock(&pHddCtx->tdls_lock);
8503#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 goto err_free_netdev;
8505 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308506
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308507 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308508 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308509
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308510#ifdef WLAN_NS_OFFLOAD
8511 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308512 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308513#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008514 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308515 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 netif_tx_disable(pAdapter->dev);
8517 //netif_tx_disable(pWlanDev);
8518 netif_carrier_off(pAdapter->dev);
8519
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308520 if (WLAN_HDD_P2P_CLIENT == session_type ||
8521 WLAN_HDD_P2P_DEVICE == session_type)
8522 {
8523 /* Initialize the work queue to defer the
8524 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308525 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308526 hdd_p2p_roc_work_queue);
8527 }
8528
Jeff Johnson295189b2012-06-20 16:38:30 -07008529 break;
8530 }
8531
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 case WLAN_HDD_SOFTAP:
8534 {
8535 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8536 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308537 {
8538 hddLog(VOS_TRACE_LEVEL_FATAL,
8539 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
Jeff Johnson295189b2012-06-20 16:38:30 -07008543 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8544 NL80211_IFTYPE_AP:
8545 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 pAdapter->device_mode = session_type;
8547
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308548 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 status = hdd_init_ap_mode(pAdapter);
8550 if( VOS_STATUS_SUCCESS != status )
8551 goto err_free_netdev;
8552
Nirav Shah7e3c8132015-06-22 23:51:42 +05308553 status = hdd_sta_id_hash_attach(pAdapter);
8554 if (VOS_STATUS_SUCCESS != status)
8555 {
8556 hddLog(VOS_TRACE_LEVEL_FATAL,
8557 FL("failed to attach hash for session %d"), session_type);
8558 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8559 goto err_free_netdev;
8560 }
8561
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 status = hdd_register_hostapd( pAdapter, rtnl_held );
8563 if( VOS_STATUS_SUCCESS != status )
8564 {
c_hpothu002231a2015-02-05 14:58:51 +05308565 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 goto err_free_netdev;
8567 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308568 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008569 netif_tx_disable(pAdapter->dev);
8570 netif_carrier_off(pAdapter->dev);
8571
8572 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308573
8574 if (WLAN_HDD_P2P_GO == session_type)
8575 {
8576 /* Initialize the work queue to
8577 * defer the back to back RoC request */
8578 INIT_DELAYED_WORK(&pAdapter->roc_work,
8579 hdd_p2p_roc_work_queue);
8580 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308581
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 break;
8583 }
8584 case WLAN_HDD_MONITOR:
8585 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8587 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308588 {
8589 hddLog(VOS_TRACE_LEVEL_FATAL,
8590 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008593
Katya Nigame7b69a82015-04-28 15:24:06 +05308594 // Register wireless extensions
8595 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8596 {
8597 hddLog(VOS_TRACE_LEVEL_FATAL,
8598 "hdd_register_wext() failed with status code %08d [x%08x]",
8599 status, status );
8600 status = VOS_STATUS_E_FAILURE;
8601 }
8602
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8604 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008605#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8606 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8607#else
8608 pAdapter->dev->open = hdd_mon_open;
8609 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308610 pAdapter->dev->stop = hdd_mon_stop;
8611 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008612#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308613 status = hdd_register_interface( pAdapter, rtnl_held );
8614 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308615 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 hdd_init_tx_rx( pAdapter );
8617 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308618 //Stop the Interface TX queue.
8619 netif_tx_disable(pAdapter->dev);
8620 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 }
8622 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008623 case WLAN_HDD_FTM:
8624 {
8625 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8626
8627 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308628 {
8629 hddLog(VOS_TRACE_LEVEL_FATAL,
8630 FL("failed to allocate adapter for session %d"), session_type);
8631 return NULL;
8632 }
8633
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8635 * message while loading driver in FTM mode. */
8636 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8637 pAdapter->device_mode = session_type;
8638 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308639
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308640 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308641 hdd_init_tx_rx( pAdapter );
8642
8643 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308644 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308645 netif_tx_disable(pAdapter->dev);
8646 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 }
8648 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 default:
8650 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308651 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8652 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008653 VOS_ASSERT(0);
8654 return NULL;
8655 }
8656 }
8657
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 if( VOS_STATUS_SUCCESS == status )
8659 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308660 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8662 if( NULL == pHddAdapterNode )
8663 {
8664 status = VOS_STATUS_E_NOMEM;
8665 }
8666 else
8667 {
8668 pHddAdapterNode->pAdapter = pAdapter;
8669 status = hdd_add_adapter_back ( pHddCtx,
8670 pHddAdapterNode );
8671 }
8672 }
8673
8674 if( VOS_STATUS_SUCCESS != status )
8675 {
8676 if( NULL != pAdapter )
8677 {
8678 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8679 pAdapter = NULL;
8680 }
8681 if( NULL != pHddAdapterNode )
8682 {
8683 vos_mem_free( pHddAdapterNode );
8684 }
8685
8686 goto resume_bmps;
8687 }
8688
8689 if(VOS_STATUS_SUCCESS == status)
8690 {
8691 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8692
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008693 //Initialize the WoWL service
8694 if(!hdd_init_wowl(pAdapter))
8695 {
8696 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8697 goto err_free_netdev;
8698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008700 return pAdapter;
8701
8702err_free_netdev:
8703 free_netdev(pAdapter->dev);
8704 wlan_hdd_release_intf_addr( pHddCtx,
8705 pAdapter->macAddressCurrent.bytes );
8706
8707resume_bmps:
8708 //If bmps disabled enable it
8709 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8710 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308711 if (pHddCtx->hdd_wlan_suspended)
8712 {
8713 hdd_set_pwrparams(pHddCtx);
8714 }
8715 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 }
8717 return NULL;
8718}
8719
8720VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8721 tANI_U8 rtnl_held )
8722{
8723 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8724 VOS_STATUS status;
8725
8726 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8727 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308728 {
8729 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8730 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308732 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008733
8734 while ( pCurrent->pAdapter != pAdapter )
8735 {
8736 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8737 if( VOS_STATUS_SUCCESS != status )
8738 break;
8739
8740 pCurrent = pNext;
8741 }
8742 pAdapterNode = pCurrent;
8743 if( VOS_STATUS_SUCCESS == status )
8744 {
8745 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8746 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308747
8748#ifdef FEATURE_WLAN_TDLS
8749
8750 /* A Mutex Lock is introduced while changing/initializing the mode to
8751 * protect the concurrent access for the Adapters by TDLS module.
8752 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308753 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308754#endif
8755
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 hdd_remove_adapter( pHddCtx, pAdapterNode );
8757 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008758 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008759
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308760#ifdef FEATURE_WLAN_TDLS
8761 mutex_unlock(&pHddCtx->tdls_lock);
8762#endif
8763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764
8765 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308766 if ((!vos_concurrent_open_sessions_running()) &&
8767 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8768 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308770 if (pHddCtx->hdd_wlan_suspended)
8771 {
8772 hdd_set_pwrparams(pHddCtx);
8773 }
8774 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 }
8776
8777 return VOS_STATUS_SUCCESS;
8778 }
8779
8780 return VOS_STATUS_E_FAILURE;
8781}
8782
8783VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8784{
8785 hdd_adapter_list_node_t *pHddAdapterNode;
8786 VOS_STATUS status;
8787
8788 ENTER();
8789
8790 do
8791 {
8792 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8793 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8794 {
8795 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8796 vos_mem_free( pHddAdapterNode );
8797 }
8798 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8799
8800 EXIT();
8801
8802 return VOS_STATUS_SUCCESS;
8803}
8804
8805void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8806{
8807 v_U8_t addIE[1] = {0};
8808
8809 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8810 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8811 eANI_BOOLEAN_FALSE) )
8812 {
8813 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008814 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816
8817 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8818 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8819 eANI_BOOLEAN_FALSE) )
8820 {
8821 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008822 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 }
8824
8825 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8826 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8827 eANI_BOOLEAN_FALSE) )
8828 {
8829 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008830 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 }
8832}
8833
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308834VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8835 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008836{
8837 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8838 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308839 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308841 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308842 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308843 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008844
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308845 if (pHddCtx->isLogpInProgress) {
8846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8847 "%s:LOGP in Progress. Ignore!!!",__func__);
8848 return VOS_STATUS_E_FAILURE;
8849 }
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308852
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308853 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 switch(pAdapter->device_mode)
8855 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308856 case WLAN_HDD_IBSS:
8857 if ( VOS_TRUE == bCloseSession )
8858 {
8859 status = hdd_sta_id_hash_detach(pAdapter);
8860 if (status != VOS_STATUS_SUCCESS)
8861 hddLog(VOS_TRACE_LEVEL_ERROR,
8862 FL("sta id hash detach failed"));
8863 }
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 case WLAN_HDD_INFRA_STATION:
8866 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008867 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308868 {
8869 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05308870#ifdef FEATURE_WLAN_TDLS
8871 mutex_lock(&pHddCtx->tdls_lock);
8872 wlan_hdd_tdls_exit(pAdapter, TRUE);
8873 mutex_unlock(&pHddCtx->tdls_lock);
8874#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308875 if( hdd_connIsConnected(pstation) ||
8876 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 {
8878 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
8879 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
8880 pAdapter->sessionId,
8881 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
8882 else
8883 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
8884 pAdapter->sessionId,
8885 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05308886 /* Success implies disconnect command got queued up successfully
8887 * Or cmd not queued as scan for SSID is in progress
8888 */
8889 if((eHAL_STATUS_SUCCESS == halStatus) ||
8890 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308892 ret = wait_for_completion_interruptible_timeout(
8893 &pAdapter->disconnect_comp_var,
8894 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05308895 if (ret <= 0 &&
8896 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308897 {
8898 hddLog(VOS_TRACE_LEVEL_ERROR,
8899 "%s: wait on disconnect_comp_var failed %ld",
8900 __func__, ret);
8901 }
8902 }
8903 else
8904 {
8905 hddLog(LOGE, "%s: failed to post disconnect event to SME",
8906 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 }
8908 memset(&wrqu, '\0', sizeof(wrqu));
8909 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8910 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
8911 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
8912 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308913 else if(pstation->conn_info.connState ==
8914 eConnectionState_Disconnecting)
8915 {
8916 ret = wait_for_completion_interruptible_timeout(
8917 &pAdapter->disconnect_comp_var,
8918 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8919 if (ret <= 0)
8920 {
8921 hddLog(VOS_TRACE_LEVEL_ERROR,
8922 FL("wait on disconnect_comp_var failed %ld"), ret);
8923 }
8924 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308925 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05308927 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05308929 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
8930 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308931 {
8932 while (pAdapter->is_roc_inprogress)
8933 {
8934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8935 "%s: ROC in progress for session %d!!!",
8936 __func__, pAdapter->sessionId);
8937 // waiting for ROC to expire
8938 msleep(500);
8939 /* In GO present case , if retry exceeds 3,
8940 it means something went wrong. */
8941 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
8942 {
8943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8944 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05308945 if (eHAL_STATUS_SUCCESS !=
8946 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
8947 pAdapter->sessionId ))
8948 {
8949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8950 FL("Failed to Cancel Remain on Channel"));
8951 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308952 wait_for_completion_interruptible_timeout(
8953 &pAdapter->cancel_rem_on_chan_var,
8954 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
8955 break;
8956 }
8957 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308958 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308959 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308960#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308961 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308962#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308963
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308964 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308965
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308966 /* It is possible that the caller of this function does not
8967 * wish to close the session
8968 */
8969 if (VOS_TRUE == bCloseSession &&
8970 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 {
8972 INIT_COMPLETION(pAdapter->session_close_comp_var);
8973 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308974 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
8975 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308977 unsigned long ret;
8978
Jeff Johnson295189b2012-06-20 16:38:30 -07008979 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308980 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308981 &pAdapter->session_close_comp_var,
8982 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308983 if ( 0 >= ret)
8984 {
8985 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308986 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008988 }
8989 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 break;
8992
8993 case WLAN_HDD_SOFTAP:
8994 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05308995 if ( VOS_TRUE == bCloseSession )
8996 {
8997 status = hdd_sta_id_hash_detach(pAdapter);
8998 if (status != VOS_STATUS_SUCCESS)
8999 hddLog(VOS_TRACE_LEVEL_ERROR,
9000 FL("sta id hash detach failed"));
9001 }
9002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309004 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9005 while (pAdapter->is_roc_inprogress) {
9006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9007 "%s: ROC in progress for session %d!!!",
9008 __func__, pAdapter->sessionId);
9009 msleep(500);
9010 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9012 "%s: ROC completion is not received.!!!", __func__);
9013 WLANSAP_CancelRemainOnChannel(
9014 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9015 wait_for_completion_interruptible_timeout(
9016 &pAdapter->cancel_rem_on_chan_var,
9017 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9018 break;
9019 }
9020 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309021
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309022 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 mutex_lock(&pHddCtx->sap_lock);
9025 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9026 {
9027 VOS_STATUS status;
9028 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9029
9030 //Stop Bss.
9031 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9032 if (VOS_IS_STATUS_SUCCESS(status))
9033 {
9034 hdd_hostapd_state_t *pHostapdState =
9035 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9036
9037 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9038
9039 if (!VOS_IS_STATUS_SUCCESS(status))
9040 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309041 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9042 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 }
9044 }
9045 else
9046 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009047 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 }
9049 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309050 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009051
9052 if (eHAL_STATUS_FAILURE ==
9053 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9054 0, NULL, eANI_BOOLEAN_FALSE))
9055 {
9056 hddLog(LOGE,
9057 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009058 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 }
9060
9061 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9062 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9063 eANI_BOOLEAN_FALSE) )
9064 {
9065 hddLog(LOGE,
9066 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9067 }
9068
9069 // Reset WNI_CFG_PROBE_RSP Flags
9070 wlan_hdd_reset_prob_rspies(pAdapter);
9071 kfree(pAdapter->sessionCtx.ap.beacon);
9072 pAdapter->sessionCtx.ap.beacon = NULL;
9073 }
9074 mutex_unlock(&pHddCtx->sap_lock);
9075 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009076
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 case WLAN_HDD_MONITOR:
9078 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 default:
9081 break;
9082 }
9083
9084 EXIT();
9085 return VOS_STATUS_SUCCESS;
9086}
9087
9088VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9089{
9090 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9091 VOS_STATUS status;
9092 hdd_adapter_t *pAdapter;
9093
9094 ENTER();
9095
9096 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9097
9098 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9099 {
9100 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009101
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309102 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009103
9104 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9105 pAdapterNode = pNext;
9106 }
9107
9108 EXIT();
9109
9110 return VOS_STATUS_SUCCESS;
9111}
9112
Rajeev Kumarf999e582014-01-09 17:33:29 -08009113
9114#ifdef FEATURE_WLAN_BATCH_SCAN
9115/**---------------------------------------------------------------------------
9116
9117 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9118 structures
9119
9120 \param - pAdapter Pointer to HDD adapter
9121
9122 \return - None
9123
9124 --------------------------------------------------------------------------*/
9125void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9126{
9127 tHddBatchScanRsp *pNode;
9128 tHddBatchScanRsp *pPrev;
9129
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309130 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009131 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309132 hddLog(VOS_TRACE_LEVEL_ERROR,
9133 "%s: Adapter context is Null", __func__);
9134 return;
9135 }
9136
9137 pNode = pAdapter->pBatchScanRsp;
9138 while (pNode)
9139 {
9140 pPrev = pNode;
9141 pNode = pNode->pNext;
9142 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009143 }
9144
9145 pAdapter->pBatchScanRsp = NULL;
9146 pAdapter->numScanList = 0;
9147 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9148 pAdapter->prev_batch_id = 0;
9149
9150 return;
9151}
9152#endif
9153
9154
Jeff Johnson295189b2012-06-20 16:38:30 -07009155VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9156{
9157 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9158 VOS_STATUS status;
9159 hdd_adapter_t *pAdapter;
9160
9161 ENTER();
9162
9163 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9164
9165 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9166 {
9167 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309168 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 netif_tx_disable(pAdapter->dev);
9170 netif_carrier_off(pAdapter->dev);
9171
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009172 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9173
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309175
Katya Nigam1fd24402015-02-16 14:52:19 +05309176 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9177 hdd_ibss_deinit_tx_rx(pAdapter);
9178
Nirav Shah7e3c8132015-06-22 23:51:42 +05309179 status = hdd_sta_id_hash_detach(pAdapter);
9180 if (status != VOS_STATUS_SUCCESS)
9181 hddLog(VOS_TRACE_LEVEL_ERROR,
9182 FL("sta id hash detach failed for session id %d"),
9183 pAdapter->sessionId);
9184
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309185 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9186
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309187 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9188 {
9189 hdd_wmm_adapter_close( pAdapter );
9190 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009192
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309193 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9194 {
9195 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9196 }
9197
Rajeev Kumarf999e582014-01-09 17:33:29 -08009198#ifdef FEATURE_WLAN_BATCH_SCAN
9199 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9200 {
9201 hdd_deinit_batch_scan(pAdapter);
9202 }
9203#endif
9204
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309205#ifdef FEATURE_WLAN_TDLS
9206 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309207 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309208 mutex_unlock(&pHddCtx->tdls_lock);
9209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9211 pAdapterNode = pNext;
9212 }
9213
9214 EXIT();
9215
9216 return VOS_STATUS_SUCCESS;
9217}
9218
9219VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9220{
9221 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9222 VOS_STATUS status;
9223 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309224 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009225
9226 ENTER();
9227
9228 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9229
9230 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9231 {
9232 pAdapter = pAdapterNode->pAdapter;
9233
Kumar Anand82c009f2014-05-29 00:29:42 -07009234 hdd_wmm_init( pAdapter );
9235
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 switch(pAdapter->device_mode)
9237 {
9238 case WLAN_HDD_INFRA_STATION:
9239 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009240 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309241
9242 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9243
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 hdd_init_station_mode(pAdapter);
9245 /* Open the gates for HDD to receive Wext commands */
9246 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009247 pHddCtx->scan_info.mScanPending = FALSE;
9248 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
9250 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309251 if (!pHddCtx->isLogpInProgress)
9252 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253
9254 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309255 if (eConnectionState_Associated == connState ||
9256 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 {
9258 union iwreq_data wrqu;
9259 memset(&wrqu, '\0', sizeof(wrqu));
9260 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9261 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9262 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009263 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009264
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309266 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309267 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309269 else if (eConnectionState_Connecting == connState)
9270 {
9271 /*
9272 * Indicate connect failure to supplicant if we were in the
9273 * process of connecting
9274 */
9275 cfg80211_connect_result(pAdapter->dev, NULL,
9276 NULL, 0, NULL, 0,
9277 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9278 GFP_KERNEL);
9279 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 break;
9281
9282 case WLAN_HDD_SOFTAP:
9283 /* softAP can handle SSR */
9284 break;
9285
9286 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009289 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 break;
9291
9292 case WLAN_HDD_MONITOR:
9293 /* monitor interface start */
9294 break;
9295 default:
9296 break;
9297 }
9298
9299 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9300 pAdapterNode = pNext;
9301 }
9302
9303 EXIT();
9304
9305 return VOS_STATUS_SUCCESS;
9306}
9307
9308VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9309{
9310 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9311 hdd_adapter_t *pAdapter;
9312 VOS_STATUS status;
9313 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309314 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009315
9316 ENTER();
9317
9318 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9319
9320 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9321 {
9322 pAdapter = pAdapterNode->pAdapter;
9323
9324 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9325 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9326 {
9327 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9328 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9329
Abhishek Singhf4669da2014-05-26 15:07:49 +05309330 hddLog(VOS_TRACE_LEVEL_INFO,
9331 "%s: Set HDD connState to eConnectionState_NotConnected",
9332 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309333 spin_lock_bh(&pAdapter->lock_for_active_session);
9334 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9335 {
9336 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309339 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 init_completion(&pAdapter->disconnect_comp_var);
9341 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9342 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309344 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 &pAdapter->disconnect_comp_var,
9346 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309347 if (0 >= ret)
9348 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9349 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009350
9351 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9352 pHddCtx->isAmpAllowed = VOS_FALSE;
9353 sme_RoamConnect(pHddCtx->hHal,
9354 pAdapter->sessionId, &(pWextState->roamProfile),
9355 &roamId);
9356 }
9357
9358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9359 pAdapterNode = pNext;
9360 }
9361
9362 EXIT();
9363
9364 return VOS_STATUS_SUCCESS;
9365}
9366
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009367void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9368{
9369 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9370 VOS_STATUS status;
9371 hdd_adapter_t *pAdapter;
9372 hdd_station_ctx_t *pHddStaCtx;
9373 hdd_ap_ctx_t *pHddApCtx;
9374 hdd_hostapd_state_t * pHostapdState;
9375 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9376 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9377 const char *p2pMode = "DEV";
9378 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009379
9380 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9381 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9382 {
9383 pAdapter = pAdapterNode->pAdapter;
9384 switch (pAdapter->device_mode) {
9385 case WLAN_HDD_INFRA_STATION:
9386 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9387 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9388 staChannel = pHddStaCtx->conn_info.operationChannel;
9389 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9390 }
9391 break;
9392 case WLAN_HDD_P2P_CLIENT:
9393 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9394 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9395 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9396 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9397 p2pMode = "CLI";
9398 }
9399 break;
9400 case WLAN_HDD_P2P_GO:
9401 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9402 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9403 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9404 p2pChannel = pHddApCtx->operatingChannel;
9405 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9406 }
9407 p2pMode = "GO";
9408 break;
9409 case WLAN_HDD_SOFTAP:
9410 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9411 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9412 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9413 apChannel = pHddApCtx->operatingChannel;
9414 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9415 }
9416 break;
9417 default:
9418 break;
9419 }
9420 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9421 pAdapterNode = pNext;
9422 }
9423 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9424 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9425 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309426 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009427 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9428 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309429 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009430 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9431 }
9432 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309433 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009434 apChannel, MAC_ADDR_ARRAY(apBssid));
9435 }
9436
9437 if (p2pChannel > 0 && apChannel > 0) {
9438 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9439 }
9440}
9441
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009442bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009443{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009444 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009445}
9446
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009447/* Once SSR is disabled then it cannot be set. */
9448void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009449{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009450 if (HDD_SSR_DISABLED == isSsrRequired)
9451 return;
9452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 isSsrRequired = value;
9454}
9455
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309456void hdd_set_pre_close( hdd_context_t *pHddCtx)
9457{
9458 sme_PreClose(pHddCtx->hHal);
9459}
9460
Jeff Johnson295189b2012-06-20 16:38:30 -07009461VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9462 hdd_adapter_list_node_t** ppAdapterNode)
9463{
9464 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309465 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9467 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309468 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 return status;
9470}
9471
9472VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9473 hdd_adapter_list_node_t* pAdapterNode,
9474 hdd_adapter_list_node_t** pNextAdapterNode)
9475{
9476 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309477 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9479 (hdd_list_node_t*) pAdapterNode,
9480 (hdd_list_node_t**)pNextAdapterNode );
9481
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309482 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 return status;
9484}
9485
9486VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9487 hdd_adapter_list_node_t* pAdapterNode)
9488{
9489 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309490 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9492 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309493 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 return status;
9495}
9496
9497VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9498 hdd_adapter_list_node_t** ppAdapterNode)
9499{
9500 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309501 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9503 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309504 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 return status;
9506}
9507
9508VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9509 hdd_adapter_list_node_t* pAdapterNode)
9510{
9511 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309512 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9514 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309515 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 return status;
9517}
9518
9519VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9520 hdd_adapter_list_node_t* pAdapterNode)
9521{
9522 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309523 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9525 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309526 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009527 return status;
9528}
9529
9530hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9531 tSirMacAddr macAddr )
9532{
9533 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9534 hdd_adapter_t *pAdapter;
9535 VOS_STATUS status;
9536
9537 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9538
9539 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9540 {
9541 pAdapter = pAdapterNode->pAdapter;
9542
9543 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9544 macAddr, sizeof(tSirMacAddr) ) )
9545 {
9546 return pAdapter;
9547 }
9548 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9549 pAdapterNode = pNext;
9550 }
9551
9552 return NULL;
9553
9554}
9555
9556hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9557{
9558 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9559 hdd_adapter_t *pAdapter;
9560 VOS_STATUS status;
9561
9562 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9563
9564 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9565 {
9566 pAdapter = pAdapterNode->pAdapter;
9567
9568 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9569 IFNAMSIZ ) )
9570 {
9571 return pAdapter;
9572 }
9573 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9574 pAdapterNode = pNext;
9575 }
9576
9577 return NULL;
9578
9579}
9580
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309581hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9582 tANI_U32 sme_session_id )
9583{
9584 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9585 hdd_adapter_t *pAdapter;
9586 VOS_STATUS vos_status;
9587
9588
9589 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9590
9591 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9592 {
9593 pAdapter = pAdapterNode->pAdapter;
9594
9595 if (pAdapter->sessionId == sme_session_id)
9596 return pAdapter;
9597
9598 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9599 pAdapterNode = pNext;
9600 }
9601
9602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9603 "%s: sme_session_id %d does not exist with host",
9604 __func__, sme_session_id);
9605
9606 return NULL;
9607}
9608
Jeff Johnson295189b2012-06-20 16:38:30 -07009609hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9610{
9611 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9612 hdd_adapter_t *pAdapter;
9613 VOS_STATUS status;
9614
9615 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9616
9617 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9618 {
9619 pAdapter = pAdapterNode->pAdapter;
9620
9621 if( pAdapter && (mode == pAdapter->device_mode) )
9622 {
9623 return pAdapter;
9624 }
9625 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9626 pAdapterNode = pNext;
9627 }
9628
9629 return NULL;
9630
9631}
9632
9633//Remove this function later
9634hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9635{
9636 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9637 hdd_adapter_t *pAdapter;
9638 VOS_STATUS status;
9639
9640 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9641
9642 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9643 {
9644 pAdapter = pAdapterNode->pAdapter;
9645
9646 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9647 {
9648 return pAdapter;
9649 }
9650
9651 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9652 pAdapterNode = pNext;
9653 }
9654
9655 return NULL;
9656
9657}
9658
Jeff Johnson295189b2012-06-20 16:38:30 -07009659/**---------------------------------------------------------------------------
9660
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309661 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009662
9663 This API returns the operating channel of the requested device mode
9664
9665 \param - pHddCtx - Pointer to the HDD context.
9666 - mode - Device mode for which operating channel is required
9667 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9668 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9669 \return - channel number. "0" id the requested device is not found OR it is not connected.
9670 --------------------------------------------------------------------------*/
9671v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9672{
9673 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9674 VOS_STATUS status;
9675 hdd_adapter_t *pAdapter;
9676 v_U8_t operatingChannel = 0;
9677
9678 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9679
9680 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9681 {
9682 pAdapter = pAdapterNode->pAdapter;
9683
9684 if( mode == pAdapter->device_mode )
9685 {
9686 switch(pAdapter->device_mode)
9687 {
9688 case WLAN_HDD_INFRA_STATION:
9689 case WLAN_HDD_P2P_CLIENT:
9690 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9691 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9692 break;
9693 case WLAN_HDD_SOFTAP:
9694 case WLAN_HDD_P2P_GO:
9695 /*softap connection info */
9696 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9697 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9698 break;
9699 default:
9700 break;
9701 }
9702
9703 break; //Found the device of interest. break the loop
9704 }
9705
9706 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9707 pAdapterNode = pNext;
9708 }
9709 return operatingChannel;
9710}
9711
9712#ifdef WLAN_FEATURE_PACKET_FILTERING
9713/**---------------------------------------------------------------------------
9714
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309715 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009716
9717 This used to set the multicast address list.
9718
9719 \param - dev - Pointer to the WLAN device.
9720 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309721 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
9723 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309724static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009725{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309726 hdd_adapter_t *pAdapter;
9727 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309729 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309732 ENTER();
9733
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309734 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309735 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009736 {
9737 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309738 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 return;
9740 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309741 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9742 ret = wlan_hdd_validate_context(pHddCtx);
9743 if (0 != ret)
9744 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309745 return;
9746 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 if (dev->flags & IFF_ALLMULTI)
9748 {
9749 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009750 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309751 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309753 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 {
9755 mc_count = netdev_mc_count(dev);
9756 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009757 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9759 {
9760 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009761 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309762 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 return;
9764 }
9765
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309766 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009767
9768 netdev_for_each_mc_addr(ha, dev) {
9769 if (i == mc_count)
9770 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309771 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9772 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309774 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309775 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 i++;
9777 }
9778 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309779
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309780 if (pHddCtx->hdd_wlan_suspended)
9781 {
9782 /*
9783 * Configure the Mcast address list to FW
9784 * If wlan is already in suspend mode
9785 */
9786 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9787 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309788 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 return;
9790}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309791
9792static void hdd_set_multicast_list(struct net_device *dev)
9793{
9794 vos_ssr_protect(__func__);
9795 __hdd_set_multicast_list(dev);
9796 vos_ssr_unprotect(__func__);
9797}
Jeff Johnson295189b2012-06-20 16:38:30 -07009798#endif
9799
9800/**---------------------------------------------------------------------------
9801
9802 \brief hdd_select_queue() -
9803
9804 This function is registered with the Linux OS for network
9805 core to decide which queue to use first.
9806
9807 \param - dev - Pointer to the WLAN device.
9808 - skb - Pointer to OS packet (sk_buff).
9809 \return - ac, Queue Index/access category corresponding to UP in IP header
9810
9811 --------------------------------------------------------------------------*/
9812v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309813 struct sk_buff *skb
9814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9815 , void *accel_priv
9816#endif
9817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9818 , select_queue_fallback_t fallback
9819#endif
9820)
Jeff Johnson295189b2012-06-20 16:38:30 -07009821{
9822 return hdd_wmm_select_queue(dev, skb);
9823}
9824
9825
9826/**---------------------------------------------------------------------------
9827
9828 \brief hdd_wlan_initial_scan() -
9829
9830 This function triggers the initial scan
9831
9832 \param - pAdapter - Pointer to the HDD adapter.
9833
9834 --------------------------------------------------------------------------*/
9835void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9836{
9837 tCsrScanRequest scanReq;
9838 tCsrChannelInfo channelInfo;
9839 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009840 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9842
9843 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9844 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9845 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9846
9847 if(sme_Is11dSupported(pHddCtx->hHal))
9848 {
9849 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9850 if ( HAL_STATUS_SUCCESS( halStatus ) )
9851 {
9852 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9853 if( !scanReq.ChannelInfo.ChannelList )
9854 {
9855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9856 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009857 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 return;
9859 }
9860 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9861 channelInfo.numOfChannels);
9862 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
9863 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009864 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009865 }
9866
9867 scanReq.scanType = eSIR_PASSIVE_SCAN;
9868 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
9869 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
9870 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
9871 }
9872 else
9873 {
9874 scanReq.scanType = eSIR_ACTIVE_SCAN;
9875 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9876 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
9877 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
9878 }
9879
9880 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
9881 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9882 {
9883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
9884 __func__, halStatus );
9885 }
9886
9887 if(sme_Is11dSupported(pHddCtx->hHal))
9888 vos_mem_free(scanReq.ChannelInfo.ChannelList);
9889}
9890
Jeff Johnson295189b2012-06-20 16:38:30 -07009891/**---------------------------------------------------------------------------
9892
9893 \brief hdd_full_power_callback() - HDD full power callback function
9894
9895 This is the function invoked by SME to inform the result of a full power
9896 request issued by HDD
9897
9898 \param - callbackcontext - Pointer to cookie
9899 \param - status - result of request
9900
9901 \return - None
9902
9903 --------------------------------------------------------------------------*/
9904static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
9905{
Jeff Johnson72a40512013-12-19 10:14:15 -08009906 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009907
9908 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309909 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009910
9911 if (NULL == callbackContext)
9912 {
9913 hddLog(VOS_TRACE_LEVEL_ERROR,
9914 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009915 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 return;
9917 }
9918
Jeff Johnson72a40512013-12-19 10:14:15 -08009919 /* there is a race condition that exists between this callback
9920 function and the caller since the caller could time out either
9921 before or while this code is executing. we use a spinlock to
9922 serialize these actions */
9923 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009924
9925 if (POWER_CONTEXT_MAGIC != pContext->magic)
9926 {
9927 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08009928 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 hddLog(VOS_TRACE_LEVEL_WARN,
9930 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009931 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 return;
9933 }
9934
Jeff Johnson72a40512013-12-19 10:14:15 -08009935 /* context is valid so caller is still waiting */
9936
9937 /* paranoia: invalidate the magic */
9938 pContext->magic = 0;
9939
9940 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08009942
9943 /* serialization is complete */
9944 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009945}
9946
Katya Nigamf0511f62015-05-05 16:40:57 +05309947void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
9948{
9949 pMonCtx->typeSubtypeBitmap = 0;
9950 if( type%10 ) /* Management Packets */
9951 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
9952 type/=10;
9953 if( type%10 ) /* Control Packets */
9954 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
9955 type/=10;
9956 if( type%10 ) /* Data Packets */
9957 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
9958}
9959
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309960VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
9961 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05309962{
9963 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309964 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05309965
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309966 if (MON_MODE_START == pMonCtx->state)
9967 monMsg.type = WDA_MON_START_REQ;
9968 else if (MON_MODE_STOP == pMonCtx->state)
9969 monMsg.type = WDA_MON_STOP_REQ;
9970 else {
9971 hddLog(VOS_TRACE_LEVEL_ERROR,
9972 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05309973 return VOS_STATUS_E_FAILURE;
9974 }
9975
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309976 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
9977 if (pMonModeReq == NULL) {
9978 hddLog(VOS_TRACE_LEVEL_ERROR,
9979 FL("fail to allocate memory for monitor mode req"));
9980 return VOS_STATUS_E_FAILURE;
9981 }
Katya Nigamf0511f62015-05-05 16:40:57 +05309982
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309983 pMonModeReq->magic = magic;
9984 pMonModeReq->cmpVar = cmpVar;
9985 pMonModeReq->data = pMonCtx;
9986 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05309987
Katya Nigamf0511f62015-05-05 16:40:57 +05309988 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309989 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05309990 monMsg.bodyval = 0;
9991
9992 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
9993 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
9994 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309995 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05309996 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309997 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05309998}
9999
Katya Nigame7b69a82015-04-28 15:24:06 +053010000void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10001{
10002 VOS_STATUS vosStatus;
10003 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010004 long ret;
10005 hdd_mon_ctx_t *pMonCtx = NULL;
10006 v_U32_t magic;
10007 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010008
Katya Nigame7b69a82015-04-28 15:24:06 +053010009 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10010 if(pAdapter == NULL || pVosContext == NULL)
10011 {
10012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10013 return ;
10014 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010015
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010016 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10017 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10018 pMonCtx->state = MON_MODE_STOP;
10019 magic = MON_MODE_MSG_MAGIC;
10020 init_completion(&cmpVar);
10021 if (VOS_STATUS_SUCCESS !=
10022 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10023 pMonCtx, hdd_monPostMsgCb)) {
10024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10025 FL("failed to post MON MODE REQ"));
10026 pMonCtx->state = MON_MODE_START;
10027 magic = 0;
10028 return;
10029 }
10030 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10031 magic = 0;
10032 if (ret <= 0 ) {
10033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10034 FL("timeout on monitor mode completion %ld"), ret);
10035 }
10036 }
10037
Katya Nigame7b69a82015-04-28 15:24:06 +053010038 hdd_UnregisterWext(pAdapter->dev);
10039
10040 vos_mon_stop( pVosContext );
10041
10042 vosStatus = vos_sched_close( pVosContext );
10043 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10044 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10045 "%s: Failed to close VOSS Scheduler",__func__);
10046 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10047 }
10048
10049 vosStatus = vos_nv_close();
10050 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10051 {
10052 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10053 "%s: Failed to close NV", __func__);
10054 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10055 }
10056
10057 vos_close(pVosContext);
10058
10059 #ifdef WLAN_KD_READY_NOTIFIER
10060 nl_srv_exit(pHddCtx->ptt_pid);
10061 #else
10062 nl_srv_exit();
10063 #endif
10064
Katya Nigame7b69a82015-04-28 15:24:06 +053010065 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010066}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010067/**
10068 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10069 * @ wiphy: the wiphy to validate against
10070 *
10071 * Return: void
10072 */
10073void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10074{
10075 int i =0;
10076 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10077 {
10078 if (NULL != wiphy->bands[i] &&
10079 (NULL != wiphy->bands[i]->channels))
10080 {
10081 vos_mem_free(wiphy->bands[i]->channels);
10082 wiphy->bands[i]->channels = NULL;
10083 }
10084 }
10085}
Jeff Johnson295189b2012-06-20 16:38:30 -070010086/**---------------------------------------------------------------------------
10087
10088 \brief hdd_wlan_exit() - HDD WLAN exit function
10089
10090 This is the driver exit point (invoked during rmmod)
10091
10092 \param - pHddCtx - Pointer to the HDD Context
10093
10094 \return - None
10095
10096 --------------------------------------------------------------------------*/
10097void hdd_wlan_exit(hdd_context_t *pHddCtx)
10098{
10099 eHalStatus halStatus;
10100 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10101 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010102 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010103 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010104 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010106 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010107
10108 ENTER();
10109
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010110
Katya Nigame7b69a82015-04-28 15:24:06 +053010111 if (VOS_MONITOR_MODE == hdd_get_conparam())
10112 {
10113 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10114 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010115 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010116 }
10117 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010118 {
10119 // Unloading, restart logic is no more required.
10120 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010121
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010122#ifdef FEATURE_WLAN_TDLS
10123 /* At the time of driver unloading; if tdls connection is present;
10124 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10125 * wlan_hdd_tdls_find_peer always checks for valid context;
10126 * as load/unload in progress there can be a race condition.
10127 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10128 * when tdls state is enabled.
10129 * As soon as driver set load/unload flag; tdls flag also needs
10130 * to be disabled so that hdd_rx_packet_cbk won't call
10131 * wlan_hdd_tdls_find_peer.
10132 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010133 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10134 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010135#endif
10136
c_hpothu5ab05e92014-06-13 17:34:05 +053010137 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10138 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010140 pAdapter = pAdapterNode->pAdapter;
10141 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010143 /* Disable TX on the interface, after this hard_start_xmit() will
10144 * not be called on that interface
10145 */
10146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10147 netif_tx_disable(pAdapter->dev);
10148
10149 /* Mark the interface status as "down" for outside world */
10150 netif_carrier_off(pAdapter->dev);
10151
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010152 /* DeInit the adapter. This ensures that all data packets
10153 * are freed.
10154 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010155#ifdef FEATURE_WLAN_TDLS
10156 mutex_lock(&pHddCtx->tdls_lock);
10157#endif
c_hpothu002231a2015-02-05 14:58:51 +053010158 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010159#ifdef FEATURE_WLAN_TDLS
10160 mutex_unlock(&pHddCtx->tdls_lock);
10161#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010162 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10163
10164 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010165
c_hpothu5ab05e92014-06-13 17:34:05 +053010166 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10167 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10168 {
10169 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10170 hdd_UnregisterWext(pAdapter->dev);
10171 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010172
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010174 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10175 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 }
mukul sharmabab477d2015-06-11 17:14:55 +053010177
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010178 // Cancel any outstanding scan requests. We are about to close all
10179 // of our adapters, but an adapter structure is what SME passes back
10180 // to our callback function. Hence if there are any outstanding scan
10181 // requests then there is a race condition between when the adapter
10182 // is closed and when the callback is invoked.We try to resolve that
10183 // race condition here by canceling any outstanding scans before we
10184 // close the adapters.
10185 // Note that the scans may be cancelled in an asynchronous manner,
10186 // so ideally there needs to be some kind of synchronization. Rather
10187 // than introduce a new synchronization here, we will utilize the
10188 // fact that we are about to Request Full Power, and since that is
10189 // synchronized, the expectation is that by the time Request Full
10190 // Power has completed all scans will be cancelled.
10191 if (pHddCtx->scan_info.mScanPending)
10192 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010193 if(NULL != pAdapter)
10194 {
10195 hddLog(VOS_TRACE_LEVEL_INFO,
10196 FL("abort scan mode: %d sessionId: %d"),
10197 pAdapter->device_mode,
10198 pAdapter->sessionId);
10199 }
10200 hdd_abort_mac_scan(pHddCtx,
10201 pHddCtx->scan_info.sessionId,
10202 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010203 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010205 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010206 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010207 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010208 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10209 {
10210 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10212 "%s: in middle of FTM START", __func__);
10213 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10214 msecs_to_jiffies(20000));
10215 if(!lrc)
10216 {
10217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10218 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10219 }
10220 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010221 wlan_hdd_ftm_close(pHddCtx);
10222 goto free_hdd_ctx;
10223 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010224
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 /* DeRegister with platform driver as client for Suspend/Resume */
10226 vosStatus = hddDeregisterPmOps(pHddCtx);
10227 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10228 {
10229 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10230 VOS_ASSERT(0);
10231 }
10232
10233 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10234 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10235 {
10236 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010238
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010239 //Stop the traffic monitor timer
10240 if ( VOS_TIMER_STATE_RUNNING ==
10241 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
10242 {
10243 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10244 }
10245
10246 // Destroy the traffic monitor timer
10247 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10248 &pHddCtx->tx_rx_trafficTmr)))
10249 {
10250 hddLog(VOS_TRACE_LEVEL_ERROR,
10251 "%s: Cannot deallocate Traffic monitor timer", __func__);
10252 }
10253
Bhargav Shahd0715912015-10-01 18:17:37 +053010254 if (VOS_TIMER_STATE_RUNNING ==
10255 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10256 vos_timer_stop(&pHddCtx->delack_timer);
10257 }
10258
10259 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10260 &pHddCtx->delack_timer))) {
10261 hddLog(VOS_TRACE_LEVEL_ERROR,
10262 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10263 }
10264
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010265 if (VOS_TIMER_STATE_RUNNING ==
10266 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10267 vos_timer_stop(&pHddCtx->tdls_source_timer);
10268 }
10269
10270 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 //Disable IMPS/BMPS as we do not want the device to enter any power
10273 //save mode during shutdown
10274 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10275 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10276 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10277
10278 //Ensure that device is in full power as we will touch H/W during vos_Stop
10279 init_completion(&powerContext.completion);
10280 powerContext.magic = POWER_CONTEXT_MAGIC;
10281
10282 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10283 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10284
10285 if (eHAL_STATUS_SUCCESS != halStatus)
10286 {
10287 if (eHAL_STATUS_PMC_PENDING == halStatus)
10288 {
10289 /* request was sent -- wait for the response */
10290 lrc = wait_for_completion_interruptible_timeout(
10291 &powerContext.completion,
10292 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 if (lrc <= 0)
10294 {
10295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010296 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 }
10298 }
10299 else
10300 {
10301 hddLog(VOS_TRACE_LEVEL_ERROR,
10302 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010303 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 /* continue -- need to clean up as much as possible */
10305 }
10306 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010307 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10308 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10309 {
10310 /* This will issue a dump command which will clean up
10311 BTQM queues and unblock MC thread */
10312 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10313 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010314
Jeff Johnson72a40512013-12-19 10:14:15 -080010315 /* either we never sent a request, we sent a request and received a
10316 response or we sent a request and timed out. if we never sent a
10317 request or if we sent a request and got a response, we want to
10318 clear the magic out of paranoia. if we timed out there is a
10319 race condition such that the callback function could be
10320 executing at the same time we are. of primary concern is if the
10321 callback function had already verified the "magic" but had not
10322 yet set the completion variable when a timeout occurred. we
10323 serialize these activities by invalidating the magic while
10324 holding a shared spinlock which will cause us to block if the
10325 callback is currently executing */
10326 spin_lock(&hdd_context_lock);
10327 powerContext.magic = 0;
10328 spin_unlock(&hdd_context_lock);
10329
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010330 /* If Device is shutdown, no point for SME to wait for responses
10331 from device. Pre Close SME */
10332 if(wcnss_device_is_shutdown())
10333 {
10334 sme_PreClose(pHddCtx->hHal);
10335 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010336 hdd_debugfs_exit(pHddCtx);
10337
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010338#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010339 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010340 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10341#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010342 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010343 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10344
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 // Unregister the Net Device Notifier
10346 unregister_netdevice_notifier(&hdd_netdev_notifier);
10347
Jeff Johnson295189b2012-06-20 16:38:30 -070010348 hdd_stop_all_adapters( pHddCtx );
10349
Jeff Johnson295189b2012-06-20 16:38:30 -070010350#ifdef WLAN_BTAMP_FEATURE
10351 vosStatus = WLANBAP_Stop(pVosContext);
10352 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10353 {
10354 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10355 "%s: Failed to stop BAP",__func__);
10356 }
10357#endif //WLAN_BTAMP_FEATURE
10358
10359 //Stop all the modules
10360 vosStatus = vos_stop( pVosContext );
10361 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10362 {
10363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10364 "%s: Failed to stop VOSS",__func__);
10365 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010366 if (isSsrPanicOnFailure())
10367 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 }
10369
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010372
10373 //Close the scheduler before calling vos_close to make sure no thread is
10374 // scheduled after the each module close is called i.e after all the data
10375 // structures are freed.
10376 vosStatus = vos_sched_close( pVosContext );
10377 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10378 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10379 "%s: Failed to close VOSS Scheduler",__func__);
10380 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10381 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010382#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10383 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010384 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010385#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010386 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010387 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010388
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010389#ifdef CONFIG_ENABLE_LINUX_REG
10390 vosStatus = vos_nv_close();
10391 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10392 {
10393 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10394 "%s: Failed to close NV", __func__);
10395 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10396 }
10397#endif
10398
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 //Close VOSS
10400 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10401 vos_close(pVosContext);
10402
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 //Close Watchdog
10404 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10405 vos_watchdog_close(pVosContext);
10406
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010407 //Clean up HDD Nlink Service
10408 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010409
Manjeet Singh47ee8472016-04-11 11:57:18 +053010410 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010411 wlan_free_fwr_mem_dump_buffer();
10412 memdump_deinit();
10413
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010414#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010415 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010416 {
10417 wlan_logging_sock_deactivate_svc();
10418 }
10419#endif
10420
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010421#ifdef WLAN_KD_READY_NOTIFIER
10422 nl_srv_exit(pHddCtx->ptt_pid);
10423#else
10424 nl_srv_exit();
10425#endif /* WLAN_KD_READY_NOTIFIER */
10426
Abhishek Singh00b71972016-01-07 10:51:04 +053010427#ifdef WLAN_FEATURE_RMC
10428 hdd_close_cesium_nl_sock();
10429#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010430
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 hdd_close_all_adapters( pHddCtx );
10432
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010433 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10434
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010435free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010436 /* free the power on lock from platform driver */
10437 if (free_riva_power_on_lock("wlan"))
10438 {
10439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10440 __func__);
10441 }
10442
c_hpothu78c7b602014-05-17 17:35:49 +053010443 //Free up dynamically allocated members inside HDD Adapter
10444 if (pHddCtx->cfg_ini)
10445 {
10446 kfree(pHddCtx->cfg_ini);
10447 pHddCtx->cfg_ini= NULL;
10448 }
10449
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010450 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010451 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010452 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10453 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010454 {
10455 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010456 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010457 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 if (hdd_is_ssr_required())
10460 {
10461 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010462 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 msleep(5000);
10464 }
10465 hdd_set_ssr_required (VOS_FALSE);
10466}
10467
10468
10469/**---------------------------------------------------------------------------
10470
10471 \brief hdd_update_config_from_nv() - Function to update the contents of
10472 the running configuration with parameters taken from NV storage
10473
10474 \param - pHddCtx - Pointer to the HDD global context
10475
10476 \return - VOS_STATUS_SUCCESS if successful
10477
10478 --------------------------------------------------------------------------*/
10479static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10480{
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 v_BOOL_t itemIsValid = VOS_FALSE;
10482 VOS_STATUS status;
10483 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10484 v_U8_t macLoop;
10485
10486 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10487 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10488 if(status != VOS_STATUS_SUCCESS)
10489 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010490 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 return VOS_STATUS_E_FAILURE;
10492 }
10493
10494 if (itemIsValid == VOS_TRUE)
10495 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010496 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10498 VOS_MAX_CONCURRENCY_PERSONA);
10499 if(status != VOS_STATUS_SUCCESS)
10500 {
10501 /* Get MAC from NV fail, not update CFG info
10502 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010503 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010504 return VOS_STATUS_E_FAILURE;
10505 }
10506
10507 /* If first MAC is not valid, treat all others are not valid
10508 * Then all MACs will be got from ini file */
10509 if(vos_is_macaddr_zero(&macFromNV[0]))
10510 {
10511 /* MAC address in NV file is not configured yet */
10512 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10513 return VOS_STATUS_E_INVAL;
10514 }
10515
10516 /* Get MAC address from NV, update CFG info */
10517 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10518 {
10519 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10520 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010521 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 /* This MAC is not valid, skip it
10523 * This MAC will be got from ini file */
10524 }
10525 else
10526 {
10527 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10528 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10529 VOS_MAC_ADDR_SIZE);
10530 }
10531 }
10532 }
10533 else
10534 {
10535 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10536 return VOS_STATUS_E_FAILURE;
10537 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010538
Jeff Johnson295189b2012-06-20 16:38:30 -070010539
10540 return VOS_STATUS_SUCCESS;
10541}
10542
10543/**---------------------------------------------------------------------------
10544
10545 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10546
10547 \param - pAdapter - Pointer to the HDD
10548
10549 \return - None
10550
10551 --------------------------------------------------------------------------*/
10552VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10553{
10554 eHalStatus halStatus;
10555 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010556 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010557
Jeff Johnson295189b2012-06-20 16:38:30 -070010558
10559 // Send ready indication to the HDD. This will kick off the MAC
10560 // into a 'running' state and should kick off an initial scan.
10561 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10562 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10563 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010564 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 "code %08d [x%08x]",__func__, halStatus, halStatus );
10566 return VOS_STATUS_E_FAILURE;
10567 }
10568
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010569 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10571 // And RIVA will crash
10572 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10573 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010574 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10575 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10576
10577
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 return VOS_STATUS_SUCCESS;
10579}
10580
Jeff Johnson295189b2012-06-20 16:38:30 -070010581/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010582void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010583{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010584
10585 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10586
Jeff Johnson295189b2012-06-20 16:38:30 -070010587}
10588
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010589void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010590{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010591
10592 vos_wake_lock_release(&wlan_wake_lock, reason);
10593
Jeff Johnson295189b2012-06-20 16:38:30 -070010594}
10595
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010596void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010597{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010598
10599 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10600 reason);
10601
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010602}
10603
Jeff Johnson295189b2012-06-20 16:38:30 -070010604/**---------------------------------------------------------------------------
10605
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010606 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10607 information between Host and Riva
10608
10609 This function gets reported version of FW
10610 It also finds the version of Riva headers used to compile the host
10611 It compares the above two and prints a warning if they are different
10612 It gets the SW and HW version string
10613 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10614 indicating the features they support through a bitmap
10615
10616 \param - pHddCtx - Pointer to HDD context
10617
10618 \return - void
10619
10620 --------------------------------------------------------------------------*/
10621
10622void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10623{
10624
10625 tSirVersionType versionCompiled;
10626 tSirVersionType versionReported;
10627 tSirVersionString versionString;
10628 tANI_U8 fwFeatCapsMsgSupported = 0;
10629 VOS_STATUS vstatus;
10630
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010631 memset(&versionCompiled, 0, sizeof(versionCompiled));
10632 memset(&versionReported, 0, sizeof(versionReported));
10633
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010634 /* retrieve and display WCNSS version information */
10635 do {
10636
10637 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10638 &versionCompiled);
10639 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10640 {
10641 hddLog(VOS_TRACE_LEVEL_FATAL,
10642 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010643 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010644 break;
10645 }
10646
10647 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10648 &versionReported);
10649 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10650 {
10651 hddLog(VOS_TRACE_LEVEL_FATAL,
10652 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010653 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010654 break;
10655 }
10656
10657 if ((versionCompiled.major != versionReported.major) ||
10658 (versionCompiled.minor != versionReported.minor) ||
10659 (versionCompiled.version != versionReported.version) ||
10660 (versionCompiled.revision != versionReported.revision))
10661 {
10662 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10663 "Host expected %u.%u.%u.%u\n",
10664 WLAN_MODULE_NAME,
10665 (int)versionReported.major,
10666 (int)versionReported.minor,
10667 (int)versionReported.version,
10668 (int)versionReported.revision,
10669 (int)versionCompiled.major,
10670 (int)versionCompiled.minor,
10671 (int)versionCompiled.version,
10672 (int)versionCompiled.revision);
10673 }
10674 else
10675 {
10676 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10677 WLAN_MODULE_NAME,
10678 (int)versionReported.major,
10679 (int)versionReported.minor,
10680 (int)versionReported.version,
10681 (int)versionReported.revision);
10682 }
10683
10684 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10685 versionString,
10686 sizeof(versionString));
10687 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10688 {
10689 hddLog(VOS_TRACE_LEVEL_FATAL,
10690 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010691 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010692 break;
10693 }
10694
10695 pr_info("%s: WCNSS software version %s\n",
10696 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010697 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010698
10699 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10700 versionString,
10701 sizeof(versionString));
10702 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10703 {
10704 hddLog(VOS_TRACE_LEVEL_FATAL,
10705 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010706 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010707 break;
10708 }
10709
10710 pr_info("%s: WCNSS hardware version %s\n",
10711 WLAN_MODULE_NAME, versionString);
10712
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010713 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10714 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010715 send the message only if it the riva is 1.1
10716 minor numbers for different riva branches:
10717 0 -> (1.0)Mainline Build
10718 1 -> (1.1)Mainline Build
10719 2->(1.04) Stability Build
10720 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010721 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010722 ((versionReported.minor>=1) && (versionReported.version>=1)))
10723 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10724 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010725
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010726 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010727 {
10728#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10729 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10730 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10731#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010732 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10733 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10734 {
10735 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10736 }
10737
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010738 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010739 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010740
10741 } while (0);
10742
10743}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010744void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10745{
10746 struct sk_buff *skb;
10747 struct nlmsghdr *nlh;
10748 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010749 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010750 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010751
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010752 if (in_interrupt() || irqs_disabled() || in_atomic())
10753 flags = GFP_ATOMIC;
10754
10755 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010756
10757 if(skb == NULL) {
10758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10759 "%s: alloc_skb failed", __func__);
10760 return;
10761 }
10762
10763 nlh = (struct nlmsghdr *)skb->data;
10764 nlh->nlmsg_pid = 0; /* from kernel */
10765 nlh->nlmsg_flags = 0;
10766 nlh->nlmsg_seq = 0;
10767 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10768
10769 ani_hdr = NLMSG_DATA(nlh);
10770 ani_hdr->type = type;
10771
10772 switch(type) {
10773 case WLAN_SVC_SAP_RESTART_IND:
10774 ani_hdr->length = 0;
10775 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10776 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10777 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010778 case WLAN_SVC_WLAN_TP_IND:
10779 ani_hdr->length = len;
10780 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10781 + len));
10782 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10783 memcpy(nl_data, data, len);
10784 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10785 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010786 case WLAN_MSG_RPS_ENABLE_IND:
10787 ani_hdr->length = len;
10788 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10789 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10790 memcpy(nl_data, data, len);
10791 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10792 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010793 default:
10794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10795 "Attempt to send unknown nlink message %d", type);
10796 kfree_skb(skb);
10797 return;
10798 }
10799
10800 nl_srv_bcast(skb);
10801
10802 return;
10803}
10804
Bhargav Shahd0715912015-10-01 18:17:37 +053010805/**
10806 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10807 * @pHddCtx: Valid Global HDD context pointer
10808 * @rx_packets: Number of RX packet in perticular time
10809 *
10810 * Based on the RX packet this function calculate next value of tcp delack.
10811 * This function compare rx packet value to high and low threshold limit.
10812 *
10813 * Return: void
10814 */
10815void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10816{
10817 /* average of rx_packets and prev_rx is taken so that
10818 bus width doesnot fluctuate much */
10819 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10820 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010821
Bhargav Shahd0715912015-10-01 18:17:37 +053010822 pHddCtx->prev_rx = rx_packets;
10823 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10824 next_rx_level = TP_IND_HIGH;
10825 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10826 next_rx_level = TP_IND_LOW;
10827
10828 hdd_set_delack_value(pHddCtx, next_rx_level);
10829}
10830
10831#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10832
10833/**
10834 * hdd_tcp_delack_compute_function() - get link status
10835 * @priv: Valid Global HDD context pointer
10836 *
10837 * This function find number of RX packet during timer life span.
10838 * It request tcp delack with number of RX packet and re-configure delack timer
10839 * for tcpDelAckComputeInterval timer interval.
10840 *
10841 * Return: void
10842 */
10843void hdd_tcp_delack_compute_function(void *priv)
10844{
10845 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10846 hdd_adapter_t *pAdapter = NULL;
10847 v_U32_t rx_packets = 0;
10848 hdd_adapter_list_node_t *pAdapterNode = NULL;
10849 VOS_STATUS status = 0;
10850
10851 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10852 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10853 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10854 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10855 continue;
10856
10857 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10858 pAdapter->prev_rx_packets);
10859 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10860 }
10861
10862 hdd_request_tcp_delack(pHddCtx, rx_packets);
10863
10864 vos_timer_start(&pHddCtx->delack_timer,
10865 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
10866}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010867
10868/**---------------------------------------------------------------------------
10869
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010870 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
10871
10872 \param - pHddCtx - Pointer to the hdd context
10873
10874 \return - true if hardware supports 5GHz
10875
10876 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053010877boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010878{
10879 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
10880 * then hardware support 5Ghz.
10881 */
10882 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
10883 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010885 return true;
10886 }
10887 else
10888 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010889 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010890 __func__);
10891 return false;
10892 }
10893}
10894
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010895/**---------------------------------------------------------------------------
10896
10897 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
10898 generate function
10899
10900 This is generate the random mac address for WLAN interface
10901
10902 \param - pHddCtx - Pointer to HDD context
10903 idx - Start interface index to get auto
10904 generated mac addr.
10905 mac_addr - Mac address
10906
10907 \return - 0 for success, < 0 for failure
10908
10909 --------------------------------------------------------------------------*/
10910
10911static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
10912 int idx, v_MACADDR_t mac_addr)
10913{
10914 int i;
10915 unsigned int serialno;
10916 serialno = wcnss_get_serial_number();
10917
10918 if (0 != serialno)
10919 {
10920 /* MAC address has 3 bytes of OUI so we have a maximum of 3
10921 bytes of the serial number that can be used to generate
10922 the other 3 bytes of the MAC address. Mask off all but
10923 the lower 3 bytes (this will also make sure we don't
10924 overflow in the next step) */
10925 serialno &= 0x00FFFFFF;
10926
10927 /* we need a unique address for each session */
10928 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
10929
10930 /* autogen other Mac addresses */
10931 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
10932 {
10933 /* start with the entire default address */
10934 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
10935 /* then replace the lower 3 bytes */
10936 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
10937 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
10938 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
10939
10940 serialno++;
10941 hddLog(VOS_TRACE_LEVEL_ERROR,
10942 "%s: Derived Mac Addr: "
10943 MAC_ADDRESS_STR, __func__,
10944 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
10945 }
10946
10947 }
10948 else
10949 {
10950 hddLog(LOGE, FL("Failed to Get Serial NO"));
10951 return -1;
10952 }
10953 return 0;
10954}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010955
Katya Nigame7b69a82015-04-28 15:24:06 +053010956int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
10957{
10958 VOS_STATUS status;
10959 v_CONTEXT_t pVosContext= NULL;
10960 hdd_adapter_t *pAdapter= NULL;
10961
10962 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10963
10964 if (NULL == pVosContext)
10965 {
10966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10967 "%s: Trying to open VOSS without a PreOpen", __func__);
10968 VOS_ASSERT(0);
10969 return VOS_STATUS_E_FAILURE;
10970 }
10971
10972 status = vos_nv_open();
10973 if (!VOS_IS_STATUS_SUCCESS(status))
10974 {
10975 /* NV module cannot be initialized */
10976 hddLog( VOS_TRACE_LEVEL_FATAL,
10977 "%s: vos_nv_open failed", __func__);
10978 return VOS_STATUS_E_FAILURE;
10979 }
10980
10981 status = vos_init_wiphy_from_nv_bin();
10982 if (!VOS_IS_STATUS_SUCCESS(status))
10983 {
10984 /* NV module cannot be initialized */
10985 hddLog( VOS_TRACE_LEVEL_FATAL,
10986 "%s: vos_init_wiphy failed", __func__);
10987 goto err_vos_nv_close;
10988 }
10989
10990 status = vos_open( &pVosContext, pHddCtx->parent_dev);
10991 if ( !VOS_IS_STATUS_SUCCESS( status ))
10992 {
10993 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
10994 goto err_vos_nv_close;
10995 }
10996
10997 status = vos_mon_start( pVosContext );
10998 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10999 {
11000 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11001 goto err_vosclose;
11002 }
11003
11004 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11005 WDA_featureCapsExchange(pVosContext);
11006 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11007
11008 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11009 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11010 if( pAdapter == NULL )
11011 {
11012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11013 goto err_close_adapter;
11014 }
11015
11016 //Initialize the nlink service
11017 if(nl_srv_init() != 0)
11018 {
11019 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11020 goto err_close_adapter;
11021 }
11022 return VOS_STATUS_SUCCESS;
11023
11024err_close_adapter:
11025 hdd_close_all_adapters( pHddCtx );
11026 vos_mon_stop( pVosContext );
11027err_vosclose:
11028 status = vos_sched_close( pVosContext );
11029 if (!VOS_IS_STATUS_SUCCESS(status)) {
11030 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11031 "%s: Failed to close VOSS Scheduler", __func__);
11032 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11033 }
11034 vos_close(pVosContext );
11035
11036err_vos_nv_close:
11037 vos_nv_close();
11038
11039return status;
11040}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011041/**---------------------------------------------------------------------------
11042
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011043 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11044 completed to flush out the scan results
11045
11046 11d scan is done during driver load and is a passive scan on all
11047 channels supported by the device, 11d scans may find some APs on
11048 frequencies which are forbidden to be used in the regulatory domain
11049 the device is operating in. If these APs are notified to the supplicant
11050 it may try to connect to these APs, thus flush out all the scan results
11051 which are present in SME after 11d scan is done.
11052
11053 \return - eHalStatus
11054
11055 --------------------------------------------------------------------------*/
11056static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11057 tANI_U32 scanId, eCsrScanStatus status)
11058{
11059 ENTER();
11060
11061 sme_ScanFlushResult(halHandle, 0);
11062
11063 EXIT();
11064
11065 return eHAL_STATUS_SUCCESS;
11066}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011067/**---------------------------------------------------------------------------
11068
11069 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11070 logging is completed successfully.
11071
11072 \return - None
11073
11074 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011075void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011076{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011077 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011078
11079 if (NULL == pHddCtx)
11080 {
11081 hddLog(VOS_TRACE_LEVEL_ERROR,
11082 "%s: HDD context is NULL",__func__);
11083 return;
11084 }
11085
c_manjeecfd1efb2015-09-25 19:32:34 +053011086 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011087 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011088 {
11089 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11090 pHddCtx->mgmt_frame_logging = TRUE;
11091 }
11092 else
11093 {
11094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11095 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011096 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011097 }
11098
c_manjeecfd1efb2015-09-25 19:32:34 +053011099 /*Check feature supported by FW*/
11100 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11101 {
11102 //Store fwr mem dump size given by firmware.
11103 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11104 }
11105 else
11106 {
11107 wlan_store_fwr_mem_dump_size(0);
11108 }
11109
11110
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011111}
11112/**---------------------------------------------------------------------------
11113
11114 \brief hdd_init_frame_logging - function to initialize frame logging.
11115 Currently only Mgmt Frames are logged in both TX
11116 and Rx direction and are sent to userspace
11117 application using logger thread when queried.
11118
11119 \return - None
11120
11121 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011122void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011123{
11124 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011125 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011126
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011127 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11128 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011129 {
11130 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11131 return;
11132 }
11133
c_manjeecfd1efb2015-09-25 19:32:34 +053011134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011135 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11136 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011137 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11138 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011139
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011140 if (pHddCtx->cfg_ini->enableFWLogging ||
11141 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011142 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011143 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011144 }
11145
Sushant Kaushik46804902015-07-08 14:46:03 +053011146 if (pHddCtx->cfg_ini->enableMgmtLogging)
11147 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011148 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011149 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011150 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11151 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011152 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011153 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011154 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11155 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11156 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011157 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011158 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011159 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011160 {
11161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11162 return;
11163 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011164 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11165 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11166 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11167 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011168 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011169
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011170 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011171
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011172 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011173 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011174 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011175 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011176 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11177 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011178
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011179 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011180
11181 if (eHAL_STATUS_SUCCESS != halStatus)
11182 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011183 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11184 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011185 }
11186
11187 return;
11188}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011189
Bhargav shah23c94942015-10-13 12:48:35 +053011190static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11191{
11192 hdd_adapter_t *adapter;
11193 hdd_adapter_list_node_t *adapter_node, *next;
11194 VOS_STATUS status = VOS_STATUS_SUCCESS;
11195 struct wlan_rps_data rps_data;
11196 int count;
11197
11198 if(!hdd_ctxt->cfg_ini->rps_mask)
11199 {
11200 return;
11201 }
11202
11203 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11204 {
11205 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11206 }
11207
11208 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11209
11210 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11211 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11212 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11213
11214 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11215
11216 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11217 {
11218 adapter = adapter_node->pAdapter;
11219 if (NULL != adapter) {
11220 strlcpy(rps_data.ifname, adapter->dev->name,
11221 sizeof(rps_data.ifname));
11222 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11223 (void *)&rps_data,sizeof(rps_data));
11224 }
11225 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11226 adapter_node = next;
11227 }
11228}
11229
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011230void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11231{
11232 scan_context_t *scan_ctx =
11233 container_of(work, scan_context_t, scan_work.work);
11234
11235 if (NULL == scan_ctx)
11236 {
11237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11238 FL("scan_ctx is NULL"));
11239 return;
11240 }
11241
11242 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11243 return;
11244
11245 scan_ctx->attempt++;
11246
11247 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11248#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11249 scan_ctx->dev,
11250#endif
11251 scan_ctx->scan_request);
11252}
11253
11254int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11255 struct wiphy *wiphy,
11256#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11257 struct net_device *dev,
11258#endif
11259 struct cfg80211_scan_request *request)
11260{
11261 scan_context_t *scan_ctx;
11262
11263 ENTER();
11264 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11265 {
11266 return -1;
11267 }
11268
11269 scan_ctx = &pHddCtx->scan_ctxt;
11270
11271 scan_ctx->wiphy = wiphy;
11272#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11273 scan_ctx->dev = dev;
11274#endif
11275
11276 scan_ctx->scan_request = request;
11277
11278 EXIT();
11279 return 0;
11280}
11281
11282void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11283 struct wiphy *wiphy,
11284#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11285 struct net_device *dev,
11286#endif
11287 struct cfg80211_scan_request *request,
11288 unsigned long delay)
11289{
11290 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11291 {
11292#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11293 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11294#else
11295 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11296#endif
11297 pHddCtx->scan_ctxt.attempt = 0;
11298 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11299 }
11300 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11301}
11302
11303void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11304{
11305 scan_ctx->magic = 0;
11306 scan_ctx->attempt = 0;
11307 scan_ctx->reject = 0;
11308 scan_ctx->scan_request = NULL;
11309
11310 return;
11311}
11312
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011313/**---------------------------------------------------------------------------
11314
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 \brief hdd_wlan_startup() - HDD init function
11316
11317 This is the driver startup code executed once a WLAN device has been detected
11318
11319 \param - dev - Pointer to the underlying device
11320
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011321 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011322
11323 --------------------------------------------------------------------------*/
11324
11325int hdd_wlan_startup(struct device *dev )
11326{
11327 VOS_STATUS status;
11328 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011329 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 hdd_context_t *pHddCtx = NULL;
11331 v_CONTEXT_t pVosContext= NULL;
11332#ifdef WLAN_BTAMP_FEATURE
11333 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11334 WLANBAP_ConfigType btAmpConfig;
11335 hdd_config_t *pConfig;
11336#endif
11337 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011339 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
11341 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 /*
11343 * cfg80211: wiphy allocation
11344 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011345 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011346
11347 if(wiphy == NULL)
11348 {
11349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011350 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 pHddCtx = wiphy_priv(wiphy);
11353
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 //Initialize the adapter context to zeros.
11355 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11356
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011358 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011359 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011360
11361 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11362
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011363 /* register for riva power on lock to platform driver
11364 * Locking power early to ensure FW doesn't reset by kernel while
11365 * host driver is busy initializing itself */
11366 if (req_riva_power_on_lock("wlan"))
11367 {
11368 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11369 __func__);
11370 goto err_free_hdd_context;
11371 }
11372
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 /*Get vos context here bcoz vos_open requires it*/
11374 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11375
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011376 if(pVosContext == NULL)
11377 {
11378 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11379 goto err_free_hdd_context;
11380 }
11381
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 //Save the Global VOSS context in adapter context for future.
11383 pHddCtx->pvosContext = pVosContext;
11384
11385 //Save the adapter context in global context for future.
11386 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11387
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 pHddCtx->parent_dev = dev;
11389
11390 init_completion(&pHddCtx->full_pwr_comp_var);
11391 init_completion(&pHddCtx->standby_comp_var);
11392 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011393 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011394 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011395 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011396 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011397 init_completion(&pHddCtx->mc_sus_event_var);
11398 init_completion(&pHddCtx->tx_sus_event_var);
11399 init_completion(&pHddCtx->rx_sus_event_var);
11400
Amar Singhala49cbc52013-10-08 18:37:44 -070011401
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011402 hdd_init_ll_stats_ctx(pHddCtx);
11403
Amar Singhala49cbc52013-10-08 18:37:44 -070011404#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011405 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011406#else
11407 init_completion(&pHddCtx->driver_crda_req);
11408#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011409
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011410#ifdef WLAN_FEATURE_EXTSCAN
11411 init_completion(&pHddCtx->ext_scan_context.response_event);
11412#endif /* WLAN_FEATURE_EXTSCAN */
11413
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011414 spin_lock_init(&pHddCtx->schedScan_lock);
11415
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11417
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011418 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11419 hdd_processSpoofMacAddrRequest);
11420
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011421#ifdef FEATURE_WLAN_TDLS
11422 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11423 * invoked by other instances also) to protect the concurrent
11424 * access for the Adapters by TDLS module.
11425 */
11426 mutex_init(&pHddCtx->tdls_lock);
11427#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011428 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011429 mutex_init(&pHddCtx->wmmLock);
11430
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011431 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011432 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011433
Agarwal Ashish1f422872014-07-22 00:11:55 +053011434 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 // Load all config first as TL config is needed during vos_open
11436 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11437 if(pHddCtx->cfg_ini == NULL)
11438 {
11439 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11440 goto err_free_hdd_context;
11441 }
11442
11443 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11444
11445 // Read and parse the qcom_cfg.ini file
11446 status = hdd_parse_config_ini( pHddCtx );
11447 if ( VOS_STATUS_SUCCESS != status )
11448 {
11449 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11450 __func__, WLAN_INI_FILE);
11451 goto err_config;
11452 }
Arif Hussaind5218912013-12-05 01:10:55 -080011453#ifdef MEMORY_DEBUG
11454 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11455 vos_mem_init();
11456
11457 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11458 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11459#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011460
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011461 /* INI has been read, initialise the configuredMcastBcastFilter with
11462 * INI value as this will serve as the default value
11463 */
11464 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11465 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11466 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011467
11468 if (false == hdd_is_5g_supported(pHddCtx))
11469 {
11470 //5Ghz is not supported.
11471 if (1 != pHddCtx->cfg_ini->nBandCapability)
11472 {
11473 hddLog(VOS_TRACE_LEVEL_INFO,
11474 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11475 pHddCtx->cfg_ini->nBandCapability = 1;
11476 }
11477 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011478
11479 /* If SNR Monitoring is enabled, FW has to parse all beacons
11480 * for calcaluting and storing the average SNR, so set Nth beacon
11481 * filter to 1 to enable FW to parse all the beaocons
11482 */
11483 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11484 {
11485 /* The log level is deliberately set to WARN as overriding
11486 * nthBeaconFilter to 1 will increase power cosumption and this
11487 * might just prove helpful to detect the power issue.
11488 */
11489 hddLog(VOS_TRACE_LEVEL_WARN,
11490 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11491 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11492 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011494 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011496 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011498 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
11499 {
11500 hddLog(VOS_TRACE_LEVEL_FATAL,
11501 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11502 goto err_config;
11503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011505
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011506 // Update VOS trace levels based upon the cfg.ini
11507 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11508 pHddCtx->cfg_ini->vosTraceEnableBAP);
11509 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11510 pHddCtx->cfg_ini->vosTraceEnableTL);
11511 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11512 pHddCtx->cfg_ini->vosTraceEnableWDI);
11513 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11514 pHddCtx->cfg_ini->vosTraceEnableHDD);
11515 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11516 pHddCtx->cfg_ini->vosTraceEnableSME);
11517 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11518 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011519 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11520 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011521 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11522 pHddCtx->cfg_ini->vosTraceEnableWDA);
11523 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11524 pHddCtx->cfg_ini->vosTraceEnableSYS);
11525 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11526 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011527 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11528 pHddCtx->cfg_ini->vosTraceEnableSAP);
11529 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11530 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011531
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 // Update WDI trace levels based upon the cfg.ini
11533 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11534 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11535 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11536 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11537 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11538 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11539 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11540 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011541
Jeff Johnson88ba7742013-02-27 14:36:02 -080011542 if (VOS_FTM_MODE == hdd_get_conparam())
11543 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11545 {
11546 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11547 goto err_free_hdd_context;
11548 }
11549 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011550 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011551 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011553 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011554
Katya Nigame7b69a82015-04-28 15:24:06 +053011555 if( VOS_MONITOR_MODE == hdd_get_conparam())
11556 {
11557 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11558 {
11559 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11560 goto err_free_hdd_context;
11561 }
11562 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11563 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11564 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11565 return VOS_STATUS_SUCCESS;
11566 }
11567
Jeff Johnson88ba7742013-02-27 14:36:02 -080011568 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11570 {
11571 status = vos_watchdog_open(pVosContext,
11572 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11573
11574 if(!VOS_IS_STATUS_SUCCESS( status ))
11575 {
11576 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011577 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 }
11579 }
11580
11581 pHddCtx->isLogpInProgress = FALSE;
11582 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11583
Amar Singhala49cbc52013-10-08 18:37:44 -070011584#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011585 /* initialize the NV module. This is required so that
11586 we can initialize the channel information in wiphy
11587 from the NV.bin data. The channel information in
11588 wiphy needs to be initialized before wiphy registration */
11589
11590 status = vos_nv_open();
11591 if (!VOS_IS_STATUS_SUCCESS(status))
11592 {
11593 /* NV module cannot be initialized */
11594 hddLog( VOS_TRACE_LEVEL_FATAL,
11595 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011596 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011597 }
11598
11599 status = vos_init_wiphy_from_nv_bin();
11600 if (!VOS_IS_STATUS_SUCCESS(status))
11601 {
11602 /* NV module cannot be initialized */
11603 hddLog( VOS_TRACE_LEVEL_FATAL,
11604 "%s: vos_init_wiphy failed", __func__);
11605 goto err_vos_nv_close;
11606 }
11607
Amar Singhala49cbc52013-10-08 18:37:44 -070011608#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011609 //Initialize the nlink service
11610 if(nl_srv_init() != 0)
11611 {
11612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11613 goto err_vos_nv_close;
11614 }
11615
11616#ifdef WLAN_KD_READY_NOTIFIER
11617 pHddCtx->kd_nl_init = 1;
11618#endif /* WLAN_KD_READY_NOTIFIER */
11619
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011620 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011621 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 if ( !VOS_IS_STATUS_SUCCESS( status ))
11623 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011624 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011625 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 }
11627
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11629
11630 if ( NULL == pHddCtx->hHal )
11631 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011632 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 goto err_vosclose;
11634 }
11635
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011636 status = vos_preStart( pHddCtx->pvosContext );
11637 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11638 {
11639 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011640 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011641 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011642
Arif Hussaineaf68602013-12-30 23:10:44 -080011643 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11644 {
11645 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11646 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11647 __func__, enable_dfs_chan_scan);
11648 }
11649 if (0 == enable_11d || 1 == enable_11d)
11650 {
11651 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11653 __func__, enable_11d);
11654 }
11655
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011656 /* Note that the vos_preStart() sequence triggers the cfg download.
11657 The cfg download must occur before we update the SME config
11658 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 status = hdd_set_sme_config( pHddCtx );
11660
11661 if ( VOS_STATUS_SUCCESS != status )
11662 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011663 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011664 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011666
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 /* In the integrated architecture we update the configuration from
11668 the INI file and from NV before vOSS has been started so that
11669 the final contents are available to send down to the cCPU */
11670
11671 // Apply the cfg.ini to cfg.dat
11672 if (FALSE == hdd_update_config_dat(pHddCtx))
11673 {
11674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011675 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 }
11677
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011678 // Get mac addr from platform driver
11679 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11680
11681 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011683 /* Store the mac addr for first interface */
11684 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11685
11686 hddLog(VOS_TRACE_LEVEL_ERROR,
11687 "%s: WLAN Mac Addr: "
11688 MAC_ADDRESS_STR, __func__,
11689 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11690
11691 /* Here, passing Arg2 as 1 because we do not want to change the
11692 last 3 bytes (means non OUI bytes) of first interface mac
11693 addr.
11694 */
11695 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11696 {
11697 hddLog(VOS_TRACE_LEVEL_ERROR,
11698 "%s: Failed to generate wlan interface mac addr "
11699 "using MAC from ini file ", __func__);
11700 }
11701 }
11702 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11703 {
11704 // Apply the NV to cfg.dat
11705 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011706#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11707 /* There was not a valid set of MAC Addresses in NV. See if the
11708 default addresses were modified by the cfg.ini settings. If so,
11709 we'll use them, but if not, we'll autogenerate a set of MAC
11710 addresses based upon the device serial number */
11711
11712 static const v_MACADDR_t default_address =
11713 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011714
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011715 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11716 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 {
11718 /* cfg.ini has the default address, invoke autogen logic */
11719
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011720 /* Here, passing Arg2 as 0 because we want to change the
11721 last 3 bytes (means non OUI bytes) of all the interfaces
11722 mac addr.
11723 */
11724 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11725 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011727 hddLog(VOS_TRACE_LEVEL_ERROR,
11728 "%s: Failed to generate wlan interface mac addr "
11729 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11730 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 }
11733 else
11734#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11735 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011736 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 "%s: Invalid MAC address in NV, using MAC from ini file "
11738 MAC_ADDRESS_STR, __func__,
11739 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11740 }
11741 }
11742 {
11743 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011744
11745 /* Set the MAC Address Currently this is used by HAL to
11746 * add self sta. Remove this once self sta is added as
11747 * part of session open.
11748 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11750 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11751 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011752
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 if (!HAL_STATUS_SUCCESS( halStatus ))
11754 {
11755 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11756 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011757 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 }
11759 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011760
11761 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11762 Note: Firmware image will be read and downloaded inside vos_start API */
11763 status = vos_start( pHddCtx->pvosContext );
11764 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11765 {
11766 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011767 if (isSsrPanicOnFailure())
11768 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011769 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011770 }
11771
Leo Chang6cec3e22014-01-21 15:33:49 -080011772#ifdef FEATURE_WLAN_CH_AVOID
11773 /* Plug in avoid channel notification callback
11774 * This should happen before ADD_SELF_STA
11775 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011776
11777 /* check the Channel Avoidance is enabled */
11778 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11779 {
11780 sme_AddChAvoidCallback(pHddCtx->hHal,
11781 hdd_hostapd_ch_avoid_cb);
11782 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011783#endif /* FEATURE_WLAN_CH_AVOID */
11784
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011785 /* Exchange capability info between Host and FW and also get versioning info from FW */
11786 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011787
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011788#ifdef CONFIG_ENABLE_LINUX_REG
11789 status = wlan_hdd_init_channels(pHddCtx);
11790 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11791 {
11792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11793 __func__);
11794 goto err_vosstop;
11795 }
11796#endif
11797
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 status = hdd_post_voss_start_config( pHddCtx );
11799 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11800 {
11801 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11802 __func__);
11803 goto err_vosstop;
11804 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011805
11806#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011807 wlan_hdd_cfg80211_update_reg_info( wiphy );
11808
11809 /* registration of wiphy dev with cfg80211 */
11810 if (0 > wlan_hdd_cfg80211_register(wiphy))
11811 {
11812 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11813 goto err_vosstop;
11814 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011815#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011816
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011817#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011818 /* registration of wiphy dev with cfg80211 */
11819 if (0 > wlan_hdd_cfg80211_register(wiphy))
11820 {
11821 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11822 goto err_vosstop;
11823 }
11824
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011825 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011826 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11827 {
11828 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11829 __func__);
11830 goto err_unregister_wiphy;
11831 }
11832#endif
11833
c_hpothu4a298be2014-12-22 21:12:51 +053011834 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11835
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11837 {
11838 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11839 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11840 }
11841 else
11842 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11844 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11845 if (pAdapter != NULL)
11846 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011847 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011849 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11850 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11851 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011852
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011853 /* Generate the P2P Device Address. This consists of the device's
11854 * primary MAC address with the locally administered bit set.
11855 */
11856 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011857 }
11858 else
11859 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011860 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11861 if (p2p_dev_addr != NULL)
11862 {
11863 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
11864 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
11865 }
11866 else
11867 {
11868 hddLog(VOS_TRACE_LEVEL_FATAL,
11869 "%s: Failed to allocate mac_address for p2p_device",
11870 __func__);
11871 goto err_close_adapter;
11872 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011874
11875 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
11876 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
11877 if ( NULL == pP2pAdapter )
11878 {
11879 hddLog(VOS_TRACE_LEVEL_FATAL,
11880 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011881 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070011882 goto err_close_adapter;
11883 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011884 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011886
11887 if( pAdapter == NULL )
11888 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11890 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011892
Arif Hussain66559122013-11-21 10:11:40 -080011893 if (country_code)
11894 {
11895 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080011896 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080011897 hdd_checkandupdate_dfssetting(pAdapter, country_code);
11898#ifndef CONFIG_ENABLE_LINUX_REG
11899 hdd_checkandupdate_phymode(pAdapter, country_code);
11900#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080011901 ret = sme_ChangeCountryCode(pHddCtx->hHal,
11902 (void *)(tSmeChangeCountryCallback)
11903 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080011904 country_code,
11905 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011906 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080011907 if (eHAL_STATUS_SUCCESS == ret)
11908 {
Arif Hussaincb607082013-12-20 11:57:42 -080011909 ret = wait_for_completion_interruptible_timeout(
11910 &pAdapter->change_country_code,
11911 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
11912
11913 if (0 >= ret)
11914 {
11915 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11916 "%s: SME while setting country code timed out", __func__);
11917 }
Arif Hussain66559122013-11-21 10:11:40 -080011918 }
11919 else
11920 {
Arif Hussaincb607082013-12-20 11:57:42 -080011921 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11922 "%s: SME Change Country code from module param fail ret=%d",
11923 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080011924 }
11925 }
11926
Jeff Johnson295189b2012-06-20 16:38:30 -070011927#ifdef WLAN_BTAMP_FEATURE
11928 vStatus = WLANBAP_Open(pVosContext);
11929 if(!VOS_IS_STATUS_SUCCESS(vStatus))
11930 {
11931 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11932 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070011933 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 }
11935
11936 vStatus = BSL_Init(pVosContext);
11937 if(!VOS_IS_STATUS_SUCCESS(vStatus))
11938 {
11939 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11940 "%s: Failed to Init BSL",__func__);
11941 goto err_bap_close;
11942 }
11943 vStatus = WLANBAP_Start(pVosContext);
11944 if (!VOS_IS_STATUS_SUCCESS(vStatus))
11945 {
11946 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11947 "%s: Failed to start TL",__func__);
11948 goto err_bap_close;
11949 }
11950
11951 pConfig = pHddCtx->cfg_ini;
11952 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
11953 status = WLANBAP_SetConfig(&btAmpConfig);
11954
11955#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070011956
Mihir Shete9c238772014-10-15 14:35:16 +053011957 /*
11958 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
11959 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
11960 * which is greater than 0xf. So the below check is safe to make
11961 * sure that there is no entry for UapsdMask in the ini
11962 */
11963 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
11964 {
11965 if(IS_DYNAMIC_WMM_PS_ENABLED)
11966 {
11967 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
11968 __func__);
11969 pHddCtx->cfg_ini->UapsdMask =
11970 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
11971 }
11972 else
11973 {
11974 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
11975 __func__);
11976 pHddCtx->cfg_ini->UapsdMask =
11977 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
11978 }
11979 }
11980
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070011981#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
11982 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
11983 {
11984 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
11985 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
11986 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
11987 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
11988 }
11989#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011990
Agarwal Ashish4b87f922014-06-18 03:03:21 +053011991 wlan_hdd_tdls_init(pHddCtx);
11992
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011993 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
11994
11995 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
11996 wlan_hdd_schedule_defer_scan);
11997
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011998 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
11999
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 /* Register with platform driver as client for Suspend/Resume */
12001 status = hddRegisterPmOps(pHddCtx);
12002 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12003 {
12004 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12005#ifdef WLAN_BTAMP_FEATURE
12006 goto err_bap_stop;
12007#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012008 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012009#endif //WLAN_BTAMP_FEATURE
12010 }
12011
Yue Ma0d4891e2013-08-06 17:01:45 -070012012 /* Open debugfs interface */
12013 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12014 {
12015 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12016 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012017 }
12018
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 /* Register TM level change handler function to the platform */
12020 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12021 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12022 {
12023 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12024 goto err_unregister_pmops;
12025 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012026
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 // register net device notifier for device change notification
12028 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12029
12030 if(ret < 0)
12031 {
12032 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012033 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 }
12035
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 //Initialize the BTC service
12037 if(btc_activate_service(pHddCtx) != 0)
12038 {
12039 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012040 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 }
12042
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012043#ifdef FEATURE_OEM_DATA_SUPPORT
12044 //Initialize the OEM service
12045 if (oem_activate_service(pHddCtx) != 0)
12046 {
12047 hddLog(VOS_TRACE_LEVEL_FATAL,
12048 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012049 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012050 }
12051#endif
12052
Jeff Johnson295189b2012-06-20 16:38:30 -070012053#ifdef PTT_SOCK_SVC_ENABLE
12054 //Initialize the PTT service
12055 if(ptt_sock_activate_svc(pHddCtx) != 0)
12056 {
12057 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012058 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 }
12060#endif
12061
Abhishek Singh00b71972016-01-07 10:51:04 +053012062#ifdef WLAN_FEATURE_RMC
12063 if (hdd_open_cesium_nl_sock() < 0)
12064 {
12065 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12066 goto err_reg_netdev;
12067 }
12068#endif
12069
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012070#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12071 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12072 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012073 if(wlan_logging_sock_activate_svc(
12074 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012075 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12076 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12077 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012078 {
12079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12080 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012081 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012082 }
12083 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12084 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012085 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12086 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012087 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12088 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012089 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012090
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012091 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12092 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012093 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012094 pHddCtx->cfg_ini->enableContFWLogging ||
12095 pHddCtx->cfg_ini->enableFwrMemDump )
12096 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012097 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012098 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012099 }
12100 else
12101 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012103 }
12104
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012105#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012106
12107
Sushant Kaushik215778f2015-05-21 14:05:36 +053012108 if (vos_is_multicast_logging())
12109 wlan_logging_set_log_level();
12110
Jeff Johnson295189b2012-06-20 16:38:30 -070012111 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012113 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012114 /* Action frame registered in one adapter which will
12115 * applicable to all interfaces
12116 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012117 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012119
12120 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012121 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012122
Jeff Johnsone7245742012-09-05 17:12:55 -070012123#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12124 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012125 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012126 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012127
Jeff Johnsone7245742012-09-05 17:12:55 -070012128#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012129 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012130 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012131 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012132
Jeff Johnsone7245742012-09-05 17:12:55 -070012133
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012134 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12135 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012136
Katya Nigam5c306ea2014-06-19 15:39:54 +053012137 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012139 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012140
12141#ifdef FEATURE_WLAN_SCAN_PNO
12142 /*SME must send channel update configuration to RIVA*/
12143 sme_UpdateChannelConfig(pHddCtx->hHal);
12144#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012145 /* Send the update default channel list to the FW*/
12146 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012147
12148 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012149 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12150 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012151 sme_SetDefDot11Mode(pHddCtx->hHal);
12152
Abhishek Singha306a442013-11-07 18:39:01 +053012153#ifndef CONFIG_ENABLE_LINUX_REG
12154 /*updating wiphy so that regulatory user hints can be processed*/
12155 if (wiphy)
12156 {
12157 regulatory_hint(wiphy, "00");
12158 }
12159#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012160 // Initialize the restart logic
12161 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012162
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012163 //Register the traffic monitor timer now
12164 if ( pHddCtx->cfg_ini->dynSplitscan)
12165 {
12166 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12167 VOS_TIMER_TYPE_SW,
12168 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12169 (void *)pHddCtx);
12170 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012171 wlan_hdd_cfg80211_nan_init(pHddCtx);
12172
Bhargav Shahd0715912015-10-01 18:17:37 +053012173 mutex_init(&pHddCtx->cur_rx_level_lock);
12174 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12175 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012176 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12177 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012178
Dino Mycle6fb96c12014-06-10 11:52:40 +053012179#ifdef WLAN_FEATURE_EXTSCAN
12180 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12181 wlan_hdd_cfg80211_extscan_callback,
12182 pHddCtx);
12183#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012184
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012185#ifdef FEATURE_OEM_DATA_SUPPORT
12186 sme_OemDataRegisterCallback(pHddCtx->hHal,
12187 wlan_hdd_cfg80211_oemdata_callback,
12188 pHddCtx);
12189#endif /* FEATURE_OEM_DATA_SUPPORT */
12190
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012191 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012192#ifdef WLAN_NS_OFFLOAD
12193 // Register IPv6 notifier to notify if any change in IP
12194 // So that we can reconfigure the offload parameters
12195 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12196 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12197 if (ret)
12198 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012200 }
12201 else
12202 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012203 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012204 }
12205#endif
12206
12207 // Register IPv4 notifier to notify if any change in IP
12208 // So that we can reconfigure the offload parameters
12209 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12210 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12211 if (ret)
12212 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012214 }
12215 else
12216 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012218 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012219 /*Fw mem dump procfs initialization*/
12220 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012221 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012222
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 goto success;
12224
Jeff Johnson295189b2012-06-20 16:38:30 -070012225err_reg_netdev:
12226 unregister_netdevice_notifier(&hdd_netdev_notifier);
12227
Jeff Johnson295189b2012-06-20 16:38:30 -070012228err_unregister_pmops:
12229 hddDevTmUnregisterNotifyCallback(pHddCtx);
12230 hddDeregisterPmOps(pHddCtx);
12231
Yue Ma0d4891e2013-08-06 17:01:45 -070012232 hdd_debugfs_exit(pHddCtx);
12233
Jeff Johnson295189b2012-06-20 16:38:30 -070012234#ifdef WLAN_BTAMP_FEATURE
12235err_bap_stop:
12236 WLANBAP_Stop(pVosContext);
12237#endif
12238
12239#ifdef WLAN_BTAMP_FEATURE
12240err_bap_close:
12241 WLANBAP_Close(pVosContext);
12242#endif
12243
Jeff Johnson295189b2012-06-20 16:38:30 -070012244err_close_adapter:
12245 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012246#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012247err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012248#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012249 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012250 hdd_wlan_free_wiphy_channels(wiphy);
12251
Jeff Johnson295189b2012-06-20 16:38:30 -070012252err_vosstop:
12253 vos_stop(pVosContext);
12254
Amar Singhala49cbc52013-10-08 18:37:44 -070012255err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 status = vos_sched_close( pVosContext );
12257 if (!VOS_IS_STATUS_SUCCESS(status)) {
12258 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12259 "%s: Failed to close VOSS Scheduler", __func__);
12260 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12261 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012262 vos_close(pVosContext );
12263
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012264err_nl_srv:
12265#ifdef WLAN_KD_READY_NOTIFIER
12266 nl_srv_exit(pHddCtx->ptt_pid);
12267#else
12268 nl_srv_exit();
12269#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012270err_vos_nv_close:
12271
c_hpothue6a36282014-03-19 12:27:38 +053012272#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012273 vos_nv_close();
12274
c_hpothu70f8d812014-03-22 22:59:23 +053012275#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012276
12277err_wdclose:
12278 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12279 vos_watchdog_close(pVosContext);
12280
Jeff Johnson295189b2012-06-20 16:38:30 -070012281err_config:
12282 kfree(pHddCtx->cfg_ini);
12283 pHddCtx->cfg_ini= NULL;
12284
12285err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012286 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012287 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 wiphy_free(wiphy) ;
12289 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 VOS_BUG(1);
12291
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012292 if (hdd_is_ssr_required())
12293 {
12294 /* WDI timeout had happened during load, so SSR is needed here */
12295 subsystem_restart("wcnss");
12296 msleep(5000);
12297 }
12298 hdd_set_ssr_required (VOS_FALSE);
12299
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012300 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012301
12302success:
12303 EXIT();
12304 return 0;
12305}
12306
12307/**---------------------------------------------------------------------------
12308
Jeff Johnson32d95a32012-09-10 13:15:23 -070012309 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012310
Jeff Johnson32d95a32012-09-10 13:15:23 -070012311 This is the driver entry point - called in different timeline depending
12312 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012313
12314 \param - None
12315
12316 \return - 0 for success, non zero for failure
12317
12318 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012319static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012320{
12321 VOS_STATUS status;
12322 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 struct device *dev = NULL;
12324 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012325#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12326 int max_retries = 0;
12327#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012328#ifdef HAVE_CBC_DONE
12329 int max_cbc_retries = 0;
12330#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012331
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012332#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12333 wlan_logging_sock_init_svc();
12334#endif
12335
Jeff Johnson295189b2012-06-20 16:38:30 -070012336 ENTER();
12337
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012338 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012339
12340 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12341 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12342
Jeff Johnson295189b2012-06-20 16:38:30 -070012343#ifdef ANI_BUS_TYPE_PCI
12344
12345 dev = wcnss_wlan_get_device();
12346
12347#endif // ANI_BUS_TYPE_PCI
12348
12349#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012350
12351#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12352 /* wait until WCNSS driver downloads NV */
12353 while (!wcnss_device_ready() && 5 >= ++max_retries) {
12354 msleep(1000);
12355 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012356
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012357 if (max_retries >= 5) {
12358 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012359 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012360#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12361 wlan_logging_sock_deinit_svc();
12362#endif
12363
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012364 return -ENODEV;
12365 }
12366#endif
12367
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012368#ifdef HAVE_CBC_DONE
12369 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12370 msleep(1000);
12371 }
12372 if (max_cbc_retries >= 10) {
12373 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12374 }
12375#endif
12376
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 dev = wcnss_wlan_get_device();
12378#endif // ANI_BUS_TYPE_PLATFORM
12379
12380
12381 do {
12382 if (NULL == dev) {
12383 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12384 ret_status = -1;
12385 break;
12386 }
12387
Jeff Johnson295189b2012-06-20 16:38:30 -070012388#ifdef TIMER_MANAGER
12389 vos_timer_manager_init();
12390#endif
12391
12392 /* Preopen VOSS so that it is ready to start at least SAL */
12393 status = vos_preOpen(&pVosContext);
12394
12395 if (!VOS_IS_STATUS_SUCCESS(status))
12396 {
12397 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12398 ret_status = -1;
12399 break;
12400 }
12401
Sushant Kaushik02beb352015-06-04 15:15:01 +053012402 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012403 hdd_register_debug_callback();
12404
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012405#ifndef MODULE
12406 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12407 */
12408 hdd_set_conparam((v_UINT_t)con_mode);
12409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012410
12411 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012412 if (hdd_wlan_startup(dev))
12413 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012414 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012415 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 vos_preClose( &pVosContext );
12417 ret_status = -1;
12418 break;
12419 }
12420
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 } while (0);
12422
12423 if (0 != ret_status)
12424 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012425#ifdef TIMER_MANAGER
12426 vos_timer_exit();
12427#endif
12428#ifdef MEMORY_DEBUG
12429 vos_mem_exit();
12430#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012431 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012432#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12433 wlan_logging_sock_deinit_svc();
12434#endif
12435
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12437 }
12438 else
12439 {
12440 //Send WLAN UP indication to Nlink Service
12441 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12442
12443 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 }
12445
12446 EXIT();
12447
12448 return ret_status;
12449}
12450
Jeff Johnson32d95a32012-09-10 13:15:23 -070012451/**---------------------------------------------------------------------------
12452
12453 \brief hdd_module_init() - Init Function
12454
12455 This is the driver entry point (invoked when module is loaded using insmod)
12456
12457 \param - None
12458
12459 \return - 0 for success, non zero for failure
12460
12461 --------------------------------------------------------------------------*/
12462#ifdef MODULE
12463static int __init hdd_module_init ( void)
12464{
12465 return hdd_driver_init();
12466}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012467#else /* #ifdef MODULE */
12468static int __init hdd_module_init ( void)
12469{
12470 /* Driver initialization is delayed to fwpath_changed_handler */
12471 return 0;
12472}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012473#endif /* #ifdef MODULE */
12474
Jeff Johnson295189b2012-06-20 16:38:30 -070012475
12476/**---------------------------------------------------------------------------
12477
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012478 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012479
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012480 This is the driver exit point (invoked when module is unloaded using rmmod
12481 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012482
12483 \param - None
12484
12485 \return - None
12486
12487 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012488static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012489{
12490 hdd_context_t *pHddCtx = NULL;
12491 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012492 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012493 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012494
12495 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12496
12497 //Get the global vos context
12498 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12499
12500 if(!pVosContext)
12501 {
12502 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12503 goto done;
12504 }
12505
12506 //Get the HDD context.
12507 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12508
12509 if(!pHddCtx)
12510 {
12511 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12512 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012513 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12514 {
12515 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12516 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12517 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12518 hdd_wlan_exit(pHddCtx);
12519 vos_preClose( &pVosContext );
12520 goto done;
12521 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 else
12523 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012524 /* We wait for active entry threads to exit from driver
12525 * by waiting until rtnl_lock is available.
12526 */
12527 rtnl_lock();
12528 rtnl_unlock();
12529
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012530 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12531 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12532 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12533 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012535 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012536 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12537 msecs_to_jiffies(30000));
12538 if(!rc)
12539 {
12540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12541 "%s:SSR timedout, fatal error", __func__);
12542 VOS_BUG(0);
12543 }
12544 }
12545
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012546 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12547 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012548
c_hpothu8adb97b2014-12-08 19:38:20 +053012549 /* Driver Need to send country code 00 in below condition
12550 * 1) If gCountryCodePriority is set to 1; and last country
12551 * code set is through 11d. This needs to be done in case
12552 * when NV country code is 00.
12553 * This Needs to be done as when kernel store last country
12554 * code and if stored country code is not through 11d,
12555 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12556 * in next load/unload as soon as we get any country through
12557 * 11d. In sme_HandleChangeCountryCodeByUser
12558 * pMsg->countryCode will be last countryCode and
12559 * pMac->scan.countryCode11d will be country through 11d so
12560 * due to mismatch driver will disable 11d.
12561 *
12562 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012563
c_hpothu8adb97b2014-12-08 19:38:20 +053012564 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012565 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012566 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012567 {
12568 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012569 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012570 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12571 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012572
c_hpothu8adb97b2014-12-08 19:38:20 +053012573 //Do all the cleanup before deregistering the driver
12574 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 }
12576
Jeff Johnson295189b2012-06-20 16:38:30 -070012577 vos_preClose( &pVosContext );
12578
12579#ifdef TIMER_MANAGER
12580 vos_timer_exit();
12581#endif
12582#ifdef MEMORY_DEBUG
12583 vos_mem_exit();
12584#endif
12585
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012586#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12587 wlan_logging_sock_deinit_svc();
12588#endif
12589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012591 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012592
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12594}
12595
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012596/**---------------------------------------------------------------------------
12597
12598 \brief hdd_module_exit() - Exit function
12599
12600 This is the driver exit point (invoked when module is unloaded using rmmod)
12601
12602 \param - None
12603
12604 \return - None
12605
12606 --------------------------------------------------------------------------*/
12607static void __exit hdd_module_exit(void)
12608{
12609 hdd_driver_exit();
12610}
12611
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012612#ifdef MODULE
12613static int fwpath_changed_handler(const char *kmessage,
12614 struct kernel_param *kp)
12615{
Jeff Johnson76052702013-04-16 13:55:05 -070012616 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012617}
12618
12619static int con_mode_handler(const char *kmessage,
12620 struct kernel_param *kp)
12621{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012622 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012623}
12624#else /* #ifdef MODULE */
12625/**---------------------------------------------------------------------------
12626
Jeff Johnson76052702013-04-16 13:55:05 -070012627 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012628
Jeff Johnson76052702013-04-16 13:55:05 -070012629 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012630 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012631 - invoked when module parameter fwpath is modified from userspace to signal
12632 initializing the WLAN driver or when con_mode is modified from userspace
12633 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012634
12635 \return - 0 for success, non zero for failure
12636
12637 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012638static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012639{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012640 int ret_status;
12641
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012642 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012643 ret_status = hdd_driver_init();
12644 wlan_hdd_inited = ret_status ? 0 : 1;
12645 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012646 }
12647
12648 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012649
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012650 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012651
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012652 ret_status = hdd_driver_init();
12653 wlan_hdd_inited = ret_status ? 0 : 1;
12654 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012655}
12656
Jeff Johnson295189b2012-06-20 16:38:30 -070012657/**---------------------------------------------------------------------------
12658
Jeff Johnson76052702013-04-16 13:55:05 -070012659 \brief fwpath_changed_handler() - Handler Function
12660
12661 Handle changes to the fwpath parameter
12662
12663 \return - 0 for success, non zero for failure
12664
12665 --------------------------------------------------------------------------*/
12666static int fwpath_changed_handler(const char *kmessage,
12667 struct kernel_param *kp)
12668{
12669 int ret;
12670
12671 ret = param_set_copystring(kmessage, kp);
12672 if (0 == ret)
12673 ret = kickstart_driver();
12674 return ret;
12675}
12676
12677/**---------------------------------------------------------------------------
12678
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012679 \brief con_mode_handler() -
12680
12681 Handler function for module param con_mode when it is changed by userspace
12682 Dynamically linked - do nothing
12683 Statically linked - exit and init driver, as in rmmod and insmod
12684
Jeff Johnson76052702013-04-16 13:55:05 -070012685 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012686
Jeff Johnson76052702013-04-16 13:55:05 -070012687 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012688
12689 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012690static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012691{
Jeff Johnson76052702013-04-16 13:55:05 -070012692 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012693
Jeff Johnson76052702013-04-16 13:55:05 -070012694 ret = param_set_int(kmessage, kp);
12695 if (0 == ret)
12696 ret = kickstart_driver();
12697 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012698}
12699#endif /* #ifdef MODULE */
12700
12701/**---------------------------------------------------------------------------
12702
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 \brief hdd_get_conparam() -
12704
12705 This is the driver exit point (invoked when module is unloaded using rmmod)
12706
12707 \param - None
12708
12709 \return - tVOS_CON_MODE
12710
12711 --------------------------------------------------------------------------*/
12712tVOS_CON_MODE hdd_get_conparam ( void )
12713{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012714#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012715 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012716#else
12717 return (tVOS_CON_MODE)curr_con_mode;
12718#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012719}
12720void hdd_set_conparam ( v_UINT_t newParam )
12721{
12722 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012723#ifndef MODULE
12724 curr_con_mode = con_mode;
12725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012726}
12727/**---------------------------------------------------------------------------
12728
12729 \brief hdd_softap_sta_deauth() - function
12730
12731 This to take counter measure to handle deauth req from HDD
12732
12733 \param - pAdapter - Pointer to the HDD
12734
12735 \param - enable - boolean value
12736
12737 \return - None
12738
12739 --------------------------------------------------------------------------*/
12740
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012741VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12742 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012743{
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012745 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012746
12747 ENTER();
12748
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012749 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12750 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012751
12752 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012753 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012754 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012755
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012756 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012757
12758 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012759 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012760}
12761
12762/**---------------------------------------------------------------------------
12763
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012764 \brief hdd_del_all_sta() - function
12765
12766 This function removes all the stations associated on stopping AP/P2P GO.
12767
12768 \param - pAdapter - Pointer to the HDD
12769
12770 \return - None
12771
12772 --------------------------------------------------------------------------*/
12773
12774int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12775{
12776 v_U16_t i;
12777 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012778 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12779 ptSapContext pSapCtx = NULL;
12780 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12781 if(pSapCtx == NULL){
12782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12783 FL("psapCtx is NULL"));
12784 return 1;
12785 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012786 ENTER();
12787
12788 hddLog(VOS_TRACE_LEVEL_INFO,
12789 "%s: Delete all STAs associated.",__func__);
12790 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12791 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12792 )
12793 {
12794 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12795 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012796 if ((pSapCtx->aStaInfo[i].isUsed) &&
12797 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012798 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012799 struct tagCsrDelStaParams delStaParams;
12800
12801 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012802 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012803 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12804 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012805 &delStaParams);
12806 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012807 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012808 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012809 }
12810 }
12811 }
12812
12813 EXIT();
12814 return 0;
12815}
12816
12817/**---------------------------------------------------------------------------
12818
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 \brief hdd_softap_sta_disassoc() - function
12820
12821 This to take counter measure to handle deauth req from HDD
12822
12823 \param - pAdapter - Pointer to the HDD
12824
12825 \param - enable - boolean value
12826
12827 \return - None
12828
12829 --------------------------------------------------------------------------*/
12830
12831void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12832{
12833 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12834
12835 ENTER();
12836
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012837 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012838
12839 //Ignore request to disassoc bcmc station
12840 if( pDestMacAddress[0] & 0x1 )
12841 return;
12842
12843 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12844}
12845
12846void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12847{
12848 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12849
12850 ENTER();
12851
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012852 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012853
12854 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
12855}
12856
Jeff Johnson295189b2012-06-20 16:38:30 -070012857/**---------------------------------------------------------------------------
12858 *
12859 * \brief hdd_get__concurrency_mode() -
12860 *
12861 *
12862 * \param - None
12863 *
12864 * \return - CONCURRENCY MODE
12865 *
12866 * --------------------------------------------------------------------------*/
12867tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
12868{
12869 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
12870 hdd_context_t *pHddCtx;
12871
12872 if (NULL != pVosContext)
12873 {
12874 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
12875 if (NULL != pHddCtx)
12876 {
12877 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
12878 }
12879 }
12880
12881 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012882 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 return VOS_STA;
12884}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012885v_BOOL_t
12886wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
12887{
12888 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012889
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012890 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
12891 if (pAdapter == NULL)
12892 {
12893 hddLog(VOS_TRACE_LEVEL_INFO,
12894 FL("GO doesn't exist"));
12895 return TRUE;
12896 }
12897 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
12898 {
12899 hddLog(VOS_TRACE_LEVEL_INFO,
12900 FL("GO started"));
12901 return TRUE;
12902 }
12903 else
12904 /* wait till GO changes its interface to p2p device */
12905 hddLog(VOS_TRACE_LEVEL_INFO,
12906 FL("Del_bss called, avoid apps suspend"));
12907 return FALSE;
12908
12909}
Jeff Johnson295189b2012-06-20 16:38:30 -070012910/* Decide whether to allow/not the apps power collapse.
12911 * Allow apps power collapse if we are in connected state.
12912 * if not, allow only if we are in IMPS */
12913v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
12914{
12915 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080012916 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012917 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 hdd_config_t *pConfig = pHddCtx->cfg_ini;
12919 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12920 hdd_adapter_t *pAdapter = NULL;
12921 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080012922 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012923
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 if (VOS_STA_SAP_MODE == hdd_get_conparam())
12925 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012926
Yathish9f22e662012-12-10 14:21:35 -080012927 concurrent_state = hdd_get_concurrency_mode();
12928
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012929 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
12930 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
12931 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080012932#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012933
Yathish9f22e662012-12-10 14:21:35 -080012934 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012935 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080012936 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
12937 return TRUE;
12938#endif
12939
Jeff Johnson295189b2012-06-20 16:38:30 -070012940 /*loop through all adapters. TBD fix for Concurrency */
12941 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12942 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12943 {
12944 pAdapter = pAdapterNode->pAdapter;
12945 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
12946 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12947 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080012948 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053012949 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053012950 && pmcState != STOPPED && pmcState != STANDBY &&
12951 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012952 (eANI_BOOLEAN_TRUE == scanRspPending) ||
12953 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070012954 {
Mukul Sharma4be88422015-03-09 20:29:07 +053012955 if(pmcState == FULL_POWER &&
12956 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
12957 {
12958 /*
12959 * When SCO indication comes from Coex module , host will
12960 * enter in to full power mode, but this should not prevent
12961 * apps processor power collapse.
12962 */
12963 hddLog(LOG1,
12964 FL("Allow apps power collapse"
12965 "even when sco indication is set"));
12966 return TRUE;
12967 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080012968 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012969 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
12970 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 return FALSE;
12972 }
12973 }
12974 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12975 pAdapterNode = pNext;
12976 }
12977 return TRUE;
12978}
12979
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080012980/* Decides whether to send suspend notification to Riva
12981 * if any adapter is in BMPS; then it is required */
12982v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
12983{
12984 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
12985 hdd_config_t *pConfig = pHddCtx->cfg_ini;
12986
12987 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
12988 {
12989 return TRUE;
12990 }
12991 return FALSE;
12992}
12993
Jeff Johnson295189b2012-06-20 16:38:30 -070012994void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
12995{
12996 switch(mode)
12997 {
Chilam Ngc4244af2013-04-01 15:37:32 -070012998 case VOS_STA_MODE:
12999 case VOS_P2P_CLIENT_MODE:
13000 case VOS_P2P_GO_MODE:
13001 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013002 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013003 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 break;
13005 default:
13006 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013007 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013008 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13009 "Number of open sessions for mode %d = %d"),
13010 pHddCtx->concurrency_mode, mode,
13011 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013012}
13013
13014
13015void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13016{
13017 switch(mode)
13018 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013019 case VOS_STA_MODE:
13020 case VOS_P2P_CLIENT_MODE:
13021 case VOS_P2P_GO_MODE:
13022 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013023 pHddCtx->no_of_open_sessions[mode]--;
13024 if (!(pHddCtx->no_of_open_sessions[mode]))
13025 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 break;
13027 default:
13028 break;
13029 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013030 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13031 "Number of open sessions for mode %d = %d"),
13032 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13033
13034}
13035/**---------------------------------------------------------------------------
13036 *
13037 * \brief wlan_hdd_incr_active_session()
13038 *
13039 * This function increments the number of active sessions
13040 * maintained per device mode
13041 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13042 * Incase of SAP/P2P GO upon bss start it is incremented
13043 *
13044 * \param pHddCtx - HDD Context
13045 * \param mode - device mode
13046 *
13047 * \return - None
13048 *
13049 * --------------------------------------------------------------------------*/
13050void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13051{
13052 switch (mode) {
13053 case VOS_STA_MODE:
13054 case VOS_P2P_CLIENT_MODE:
13055 case VOS_P2P_GO_MODE:
13056 case VOS_STA_SAP_MODE:
13057 pHddCtx->no_of_active_sessions[mode]++;
13058 break;
13059 default:
13060 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13061 break;
13062 }
13063 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13064 mode,
13065 pHddCtx->no_of_active_sessions[mode]);
13066}
13067
13068/**---------------------------------------------------------------------------
13069 *
13070 * \brief wlan_hdd_decr_active_session()
13071 *
13072 * This function decrements the number of active sessions
13073 * maintained per device mode
13074 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13075 * Incase of SAP/P2P GO upon bss stop it is decremented
13076 *
13077 * \param pHddCtx - HDD Context
13078 * \param mode - device mode
13079 *
13080 * \return - None
13081 *
13082 * --------------------------------------------------------------------------*/
13083void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13084{
Bhargav Shahd0715912015-10-01 18:17:37 +053013085
Agarwal Ashish51325b52014-06-16 16:50:49 +053013086 switch (mode) {
13087 case VOS_STA_MODE:
13088 case VOS_P2P_CLIENT_MODE:
13089 case VOS_P2P_GO_MODE:
13090 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013091 if (pHddCtx->no_of_active_sessions[mode] > 0)
13092 pHddCtx->no_of_active_sessions[mode]--;
13093 else
13094 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13095 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013096 break;
13097 default:
13098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13099 break;
13100 }
13101 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13102 mode,
13103 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013104}
13105
Jeff Johnsone7245742012-09-05 17:12:55 -070013106/**---------------------------------------------------------------------------
13107 *
13108 * \brief wlan_hdd_restart_init
13109 *
13110 * This function initalizes restart timer/flag. An internal function.
13111 *
13112 * \param - pHddCtx
13113 *
13114 * \return - None
13115 *
13116 * --------------------------------------------------------------------------*/
13117
13118static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13119{
13120 /* Initialize */
13121 pHddCtx->hdd_restart_retries = 0;
13122 atomic_set(&pHddCtx->isRestartInProgress, 0);
13123 vos_timer_init(&pHddCtx->hdd_restart_timer,
13124 VOS_TIMER_TYPE_SW,
13125 wlan_hdd_restart_timer_cb,
13126 pHddCtx);
13127}
13128/**---------------------------------------------------------------------------
13129 *
13130 * \brief wlan_hdd_restart_deinit
13131 *
13132 * This function cleans up the resources used. An internal function.
13133 *
13134 * \param - pHddCtx
13135 *
13136 * \return - None
13137 *
13138 * --------------------------------------------------------------------------*/
13139
13140static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13141{
13142
13143 VOS_STATUS vos_status;
13144 /* Block any further calls */
13145 atomic_set(&pHddCtx->isRestartInProgress, 1);
13146 /* Cleanup */
13147 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13148 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013149 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013150 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13151 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013152 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013153
13154}
13155
13156/**---------------------------------------------------------------------------
13157 *
13158 * \brief wlan_hdd_framework_restart
13159 *
13160 * This function uses a cfg80211 API to start a framework initiated WLAN
13161 * driver module unload/load.
13162 *
13163 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13164 *
13165 *
13166 * \param - pHddCtx
13167 *
13168 * \return - VOS_STATUS_SUCCESS: Success
13169 * VOS_STATUS_E_EMPTY: Adapter is Empty
13170 * VOS_STATUS_E_NOMEM: No memory
13171
13172 * --------------------------------------------------------------------------*/
13173
13174static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13175{
13176 VOS_STATUS status = VOS_STATUS_SUCCESS;
13177 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013178 int len = (sizeof (struct ieee80211_mgmt));
13179 struct ieee80211_mgmt *mgmt = NULL;
13180
13181 /* Prepare the DEAUTH managment frame with reason code */
13182 mgmt = kzalloc(len, GFP_KERNEL);
13183 if(mgmt == NULL)
13184 {
13185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13186 "%s: memory allocation failed (%d bytes)", __func__, len);
13187 return VOS_STATUS_E_NOMEM;
13188 }
13189 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013190
13191 /* Iterate over all adapters/devices */
13192 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013193 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13194 {
13195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13196 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13197 goto end;
13198 }
13199
Jeff Johnsone7245742012-09-05 17:12:55 -070013200 do
13201 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013202 if(pAdapterNode->pAdapter &&
13203 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013204 {
13205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13206 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13207 pAdapterNode->pAdapter->dev->name,
13208 pAdapterNode->pAdapter->device_mode,
13209 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013210 /*
13211 * CFG80211 event to restart the driver
13212 *
13213 * 'cfg80211_send_unprot_deauth' sends a
13214 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13215 * of SME(Linux Kernel) state machine.
13216 *
13217 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13218 * the driver.
13219 *
13220 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013221
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13223 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13224#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013225 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013226#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013227 }
13228 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13229 pAdapterNode = pNext;
13230 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13231
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013232 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013233 /* Free the allocated management frame */
13234 kfree(mgmt);
13235
Jeff Johnsone7245742012-09-05 17:12:55 -070013236 /* Retry until we unload or reach max count */
13237 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13238 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13239
13240 return status;
13241
13242}
13243/**---------------------------------------------------------------------------
13244 *
13245 * \brief wlan_hdd_restart_timer_cb
13246 *
13247 * Restart timer callback. An internal function.
13248 *
13249 * \param - User data:
13250 *
13251 * \return - None
13252 *
13253 * --------------------------------------------------------------------------*/
13254
13255void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13256{
13257 hdd_context_t *pHddCtx = usrDataForCallback;
13258 wlan_hdd_framework_restart(pHddCtx);
13259 return;
13260
13261}
13262
13263
13264/**---------------------------------------------------------------------------
13265 *
13266 * \brief wlan_hdd_restart_driver
13267 *
13268 * This function sends an event to supplicant to restart the WLAN driver.
13269 *
13270 * This function is called from vos_wlanRestart.
13271 *
13272 * \param - pHddCtx
13273 *
13274 * \return - VOS_STATUS_SUCCESS: Success
13275 * VOS_STATUS_E_EMPTY: Adapter is Empty
13276 * VOS_STATUS_E_ALREADY: Request already in progress
13277
13278 * --------------------------------------------------------------------------*/
13279VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13280{
13281 VOS_STATUS status = VOS_STATUS_SUCCESS;
13282
13283 /* A tight check to make sure reentrancy */
13284 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13285 {
Mihir Shetefd528652014-06-23 19:07:50 +053013286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013287 "%s: WLAN restart is already in progress", __func__);
13288
13289 return VOS_STATUS_E_ALREADY;
13290 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013291 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013292#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013293 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013294#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013295
Jeff Johnsone7245742012-09-05 17:12:55 -070013296 return status;
13297}
13298
Bhargav Shahd0715912015-10-01 18:17:37 +053013299/**
13300 * hdd_get_total_sessions() - provide total number of active sessions
13301 * @pHddCtx: Valid Global HDD context pointer
13302 *
13303 * This function iterates through pAdaptors and find the number of all active
13304 * sessions. This active sessions includes connected sta, p2p client and number
13305 * of client connected to sap/p2p go.
13306 *
13307 * Return: Total number of active sessions.
13308 */
13309v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13310{
13311 v_U8_t active_session = 0;
13312 hdd_station_ctx_t *pHddStaCtx;
13313 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13314 hdd_adapter_t *pAdapter;
13315 VOS_STATUS status;
13316
13317 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13318 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13319 pAdapter = pAdapterNode->pAdapter;
13320 switch (pAdapter->device_mode) {
13321 case VOS_STA_MODE:
13322 case VOS_P2P_CLIENT_MODE:
13323 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13324 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13325 active_session += 1;
13326 break;
13327 case VOS_STA_SAP_MODE:
13328 case VOS_P2P_GO_MODE:
13329 active_session += hdd_softap_get_connected_sta(pAdapter);
13330 break;
13331 default:
13332 break;
13333 }
13334
13335 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13336 pAdapterNode = pNext;
13337 }
13338
13339 return active_session;
13340}
13341
13342/**
13343 * hdd_set_delack_value() - Set delack value
13344 * @pHddCtx: Valid Global HDD context pointer
13345 * @next_rx_level: Value to set for delack
13346 *
13347 * This function compare present value and next value of delack. If the both
13348 * are diffrent then it sets next value .
13349 *
13350 * Return: void.
13351 */
13352void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13353{
13354 if (pHddCtx->cur_rx_level != next_rx_level) {
13355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13356 "%s: TCP DELACK trigger level %d",
13357 __func__, next_rx_level);
13358 mutex_lock(&pHddCtx->cur_rx_level_lock);
13359 pHddCtx->cur_rx_level = next_rx_level;
13360 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13361 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13362 sizeof(next_rx_level));
13363 }
13364}
13365
13366/**
13367 * hdd_set_default_stop_delack_timer() - Start delack timer
13368 * @pHddCtx: Valid Global HDD context pointer
13369 *
13370 * This function stop delack timer and set delack value to default..
13371 *
13372 * Return: void.
13373 */
13374
13375void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13376{
13377 if (VOS_TIMER_STATE_RUNNING !=
13378 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13380 "%s: Can not stop timer", __func__);
13381 return;
13382 }
13383
13384 vos_timer_stop(&pHddCtx->delack_timer);
13385 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13386}
13387
13388/**
13389 * hdd_start_delack_timer() - Start delack timer
13390 * @pHddCtx: Valid Global HDD context pointer
13391 *
13392 * This function starts the delack timer for tcpDelAckComputeInterval time
13393 * interval.The default timer value is 2 second.
13394 *
13395 * Return: void.
13396 */
13397void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13398{
13399 if (VOS_TIMER_STATE_RUNNING ==
13400 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13402 "%s: Timer is already running", __func__);
13403 return;
13404 }
13405
13406 vos_timer_start(&pHddCtx->delack_timer,
13407 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13408}
13409
13410/**
13411 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13412 * @pHddCtx: Valid Global HDD context pointer
13413 *
13414 * This function updates the prev_rx_packets count from the corresponding
13415 * pAdapter states. This prev_rx_packets will diffed with the packet count
13416 * at the end of delack timer. That can give number of RX packet is spacific
13417 * time.
13418 *
13419 * Return: void.
13420 */
13421void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13422{
13423 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13424 hdd_adapter_t *pAdapter;
13425 VOS_STATUS status;
13426
13427 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13428 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13429 pAdapter = pAdapterNode->pAdapter;
13430 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13431 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13432 pAdapterNode = pNext;
13433 }
13434}
13435
13436/**
13437 * hdd_manage_delack_timer() - start\stop delack timer
13438 * @pHddCtx: Valid Global HDD context pointer
13439 *
13440 * This function check the number of concerent session present, it starts the
13441 * delack timer if only one session is present.
13442 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13443 *
13444 * Return: void.
13445 */
13446void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13447{
13448 uint8_t sessions;
13449
13450 if (!pHddCtx->cfg_ini->enable_delack) {
13451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13452 "%s: TCP DELACK is not enabled", __func__);
13453 return;
13454 }
13455
13456 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13457 if (pHddCtx->mode != 0) {
13458 hdd_set_default_stop_delack_timer(pHddCtx);
13459 return;
13460 }
13461
13462 sessions = hdd_get_total_sessions(pHddCtx);
13463 if (sessions == 1) {
13464 hdd_update_prev_rx_packet_count(pHddCtx);
13465 hdd_start_delack_timer(pHddCtx);
13466 } else {
13467 hdd_set_default_stop_delack_timer(pHddCtx);
13468 }
13469}
13470
Mihir Shetee1093ba2014-01-21 20:13:32 +053013471/**---------------------------------------------------------------------------
13472 *
13473 * \brief wlan_hdd_init_channels
13474 *
13475 * This function is used to initialize the channel list in CSR
13476 *
13477 * This function is called from hdd_wlan_startup
13478 *
13479 * \param - pHddCtx: HDD context
13480 *
13481 * \return - VOS_STATUS_SUCCESS: Success
13482 * VOS_STATUS_E_FAULT: Failure reported by SME
13483
13484 * --------------------------------------------------------------------------*/
13485static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13486{
13487 eHalStatus status;
13488
13489 status = sme_InitChannels(pHddCtx->hHal);
13490 if (HAL_STATUS_SUCCESS(status))
13491 {
13492 return VOS_STATUS_SUCCESS;
13493 }
13494 else
13495 {
13496 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13497 __func__, status);
13498 return VOS_STATUS_E_FAULT;
13499 }
13500}
13501
Mihir Shete04206452014-11-20 17:50:58 +053013502#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013503VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013504{
13505 eHalStatus status;
13506
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013507 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013508 if (HAL_STATUS_SUCCESS(status))
13509 {
13510 return VOS_STATUS_SUCCESS;
13511 }
13512 else
13513 {
13514 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13515 __func__, status);
13516 return VOS_STATUS_E_FAULT;
13517 }
13518}
Mihir Shete04206452014-11-20 17:50:58 +053013519#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013520/*
13521 * API to find if there is any STA or P2P-Client is connected
13522 */
13523VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13524{
13525 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13526}
Jeff Johnsone7245742012-09-05 17:12:55 -070013527
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013528
13529/*
13530 * API to find if the firmware will send logs using DXE channel
13531 */
13532v_U8_t hdd_is_fw_logging_enabled(void)
13533{
13534 hdd_context_t *pHddCtx;
13535
13536 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13537 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13538
Sachin Ahuja084313e2015-05-21 17:57:10 +053013539 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013540}
13541
Agarwal Ashish57e84372014-12-05 18:26:53 +053013542/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013543 * API to find if the firmware will send trace logs using DXE channel
13544 */
13545v_U8_t hdd_is_fw_ev_logging_enabled(void)
13546{
13547 hdd_context_t *pHddCtx;
13548
13549 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13550 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13551
13552 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13553}
13554/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013555 * API to find if there is any session connected
13556 */
13557VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13558{
13559 return sme_is_any_session_connected(pHddCtx->hHal);
13560}
13561
13562
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013563int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13564{
13565 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13566 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013567 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013568 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013569
13570 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013571 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013572 if (pScanInfo->mScanPending)
13573 {
c_hpothua3d45d52015-01-05 14:11:17 +053013574 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13575 eCSR_SCAN_ABORT_DEFAULT);
13576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13577 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013578
c_hpothua3d45d52015-01-05 14:11:17 +053013579 /* If there is active scan command lets wait for the completion else
13580 * there is no need to wait as scan command might be in the SME pending
13581 * command list.
13582 */
13583 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13584 {
c_hpothua3d45d52015-01-05 14:11:17 +053013585 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013586 &pScanInfo->abortscan_event_var,
13587 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013588 if (0 >= status)
13589 {
13590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013591 "%s: Timeout or Interrupt occurred while waiting for abort"
13592 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013593 return -ETIMEDOUT;
13594 }
13595 }
13596 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13597 {
13598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13599 FL("hdd_abort_mac_scan failed"));
13600 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013601 }
13602 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013603 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013604}
13605
Abhishek Singh7d624e12015-11-30 14:29:27 +053013606/**
13607 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13608 * user space
13609 * @frame_ind: Management frame data to be informed.
13610 *
13611 * This function is used to indicate management frame to
13612 * user space
13613 *
13614 * Return: None
13615 *
13616 */
13617void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13618{
13619 hdd_context_t *hdd_ctx = NULL;
13620 hdd_adapter_t *adapter = NULL;
13621 v_CONTEXT_t vos_context = NULL;
13622
13623 /* Get the global VOSS context.*/
13624 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13625 if (!vos_context) {
13626 hddLog(LOGE, FL("Global VOS context is Null"));
13627 return;
13628 }
13629 /* Get the HDD context.*/
13630 hdd_ctx =
13631 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13632
13633 if (0 != wlan_hdd_validate_context(hdd_ctx))
13634 {
13635 return;
13636 }
13637 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13638 frame_ind->sessionId);
13639
13640 if ((NULL != adapter) &&
13641 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13642 __hdd_indicate_mgmt_frame(adapter,
13643 frame_ind->frameLen,
13644 frame_ind->frameBuf,
13645 frame_ind->frameType,
13646 frame_ind->rxChan,
13647 frame_ind->rxRssi);
13648 return;
13649
13650}
13651
c_hpothu225aa7c2014-10-22 17:45:13 +053013652VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13653{
13654 hdd_adapter_t *pAdapter;
13655 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13656 VOS_STATUS vosStatus;
13657
13658 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13659 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13660 {
13661 pAdapter = pAdapterNode->pAdapter;
13662 if (NULL != pAdapter)
13663 {
13664 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13665 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13666 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13667 {
13668 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13669 pAdapter->device_mode);
13670 if (VOS_STATUS_SUCCESS !=
13671 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13672 {
13673 hddLog(LOGE, FL("failed to abort ROC"));
13674 return VOS_STATUS_E_FAILURE;
13675 }
13676 }
13677 }
13678 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13679 pAdapterNode = pNext;
13680 }
13681 return VOS_STATUS_SUCCESS;
13682}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013683
Mihir Shete0be28772015-02-17 18:42:14 +053013684hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13685{
13686 hdd_adapter_t *pAdapter;
13687 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13688 hdd_cfg80211_state_t *cfgState;
13689 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13690 VOS_STATUS vosStatus;
13691
13692 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13693 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13694 {
13695 pAdapter = pAdapterNode->pAdapter;
13696 if (NULL != pAdapter)
13697 {
13698 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13699 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13700 if (pRemainChanCtx)
13701 break;
13702 }
13703 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13704 pAdapterNode = pNext;
13705 }
13706 return pRemainChanCtx;
13707}
13708
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013709/**
13710 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13711 *
13712 * @pHddCtx: HDD context within host driver
13713 * @dfsScanMode: dfsScanMode passed from ioctl
13714 *
13715 */
13716
13717VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13718 tANI_U8 dfsScanMode)
13719{
13720 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13721 hdd_adapter_t *pAdapter;
13722 VOS_STATUS vosStatus;
13723 hdd_station_ctx_t *pHddStaCtx;
13724 eHalStatus status = eHAL_STATUS_SUCCESS;
13725
13726 if(!pHddCtx)
13727 {
13728 hddLog(LOGE, FL("HDD context is Null"));
13729 return eHAL_STATUS_FAILURE;
13730 }
13731
13732 if (pHddCtx->scan_info.mScanPending)
13733 {
13734 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13735 pHddCtx->scan_info.sessionId);
13736 hdd_abort_mac_scan(pHddCtx,
13737 pHddCtx->scan_info.sessionId,
13738 eCSR_SCAN_ABORT_DEFAULT);
13739 }
13740
13741 if (!dfsScanMode)
13742 {
13743 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13744 while ((NULL != pAdapterNode) &&
13745 (VOS_STATUS_SUCCESS == vosStatus))
13746 {
13747 pAdapter = pAdapterNode->pAdapter;
13748
13749 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13750 {
13751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13752
13753 if(!pHddStaCtx)
13754 {
13755 hddLog(LOGE, FL("HDD STA context is Null"));
13756 return eHAL_STATUS_FAILURE;
13757 }
13758
13759 /* if STA is already connected on DFS channel,
13760 disconnect immediately*/
13761 if (hdd_connIsConnected(pHddStaCtx) &&
13762 (NV_CHANNEL_DFS ==
13763 vos_nv_getChannelEnabledState(
13764 pHddStaCtx->conn_info.operationChannel)))
13765 {
13766 status = sme_RoamDisconnect(pHddCtx->hHal,
13767 pAdapter->sessionId,
13768 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13769 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13770 "sme_RoamDisconnect returned with status: %d"
13771 "for sessionid: %d"), pHddStaCtx->conn_info.
13772 operationChannel, status, pAdapter->sessionId);
13773 }
13774 }
13775
13776 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13777 &pNext);
13778 pAdapterNode = pNext;
13779 }
13780 }
13781
13782 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13783 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13784 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13785
13786 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13787 if (!HAL_STATUS_SUCCESS(status))
13788 {
13789 hddLog(LOGE,
13790 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13791 return status;
13792 }
13793
13794 return status;
13795}
13796
Nirav Shah7e3c8132015-06-22 23:51:42 +053013797static int hdd_log2_ceil(unsigned value)
13798{
13799 /* need to switch to unsigned math so that negative values
13800 * will right-shift towards 0 instead of -1
13801 */
13802 unsigned tmp = value;
13803 int log2 = -1;
13804
13805 if (value == 0)
13806 return 0;
13807
13808 while (tmp) {
13809 log2++;
13810 tmp >>= 1;
13811 }
13812 if (1U << log2 != value)
13813 log2++;
13814
13815 return log2;
13816}
13817
13818/**
13819 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13820 * @pAdapter: adapter handle
13821 *
13822 * Return: vos status
13823 */
13824VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13825{
13826 int hash_elem, log2, i;
13827
13828 spin_lock_bh( &pAdapter->sta_hash_lock);
13829 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13830 spin_unlock_bh( &pAdapter->sta_hash_lock);
13831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13832 "%s: hash already attached for session id %d",
13833 __func__, pAdapter->sessionId);
13834 return VOS_STATUS_SUCCESS;
13835 }
13836 spin_unlock_bh( &pAdapter->sta_hash_lock);
13837
13838 hash_elem = WLAN_MAX_STA_COUNT;
13839 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13840 log2 = hdd_log2_ceil(hash_elem);
13841 hash_elem = 1 << log2;
13842
13843 pAdapter->sta_id_hash.mask = hash_elem - 1;
13844 pAdapter->sta_id_hash.idx_bits = log2;
13845 pAdapter->sta_id_hash.bins =
13846 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
13847 if (!pAdapter->sta_id_hash.bins) {
13848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13849 "%s: malloc failed for session %d",
13850 __func__, pAdapter->sessionId);
13851 return VOS_STATUS_E_NOMEM;
13852 }
13853
13854 for (i = 0; i < hash_elem; i++)
13855 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
13856
13857 spin_lock_bh( &pAdapter->sta_hash_lock);
13858 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
13859 spin_unlock_bh( &pAdapter->sta_hash_lock);
13860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13861 "%s: Station ID Hash attached for session id %d",
13862 __func__, pAdapter->sessionId);
13863
13864 return VOS_STATUS_SUCCESS;
13865}
13866
13867/**
13868 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
13869 * @pAdapter: adapter handle
13870 *
13871 * Return: vos status
13872 */
13873VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
13874{
13875 int hash_elem, i;
13876 v_SIZE_t size;
13877
13878 spin_lock_bh( &pAdapter->sta_hash_lock);
13879 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
13880 spin_unlock_bh( &pAdapter->sta_hash_lock);
13881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13882 "%s: hash not initialized for session id %d",
13883 __func__, pAdapter->sessionId);
13884 return VOS_STATUS_SUCCESS;
13885 }
13886
13887 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
13888 spin_unlock_bh( &pAdapter->sta_hash_lock);
13889
13890 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
13891
13892 /* free all station info*/
13893 for (i = 0; i < hash_elem; i++) {
13894 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
13895 if (size != 0) {
13896 VOS_STATUS status;
13897 hdd_staid_hash_node_t *sta_info_node = NULL;
13898 hdd_staid_hash_node_t *next_node = NULL;
13899 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
13900 (hdd_list_node_t**) &sta_info_node );
13901
13902 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
13903 {
13904 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
13905 &sta_info_node->node);
13906 vos_mem_free(sta_info_node);
13907
13908 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
13909 (hdd_list_node_t*)sta_info_node,
13910 (hdd_list_node_t**)&next_node);
13911 sta_info_node = next_node;
13912 }
13913 }
13914 }
13915
13916 vos_mem_free(pAdapter->sta_id_hash.bins);
13917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13918 "%s: Station ID Hash detached for session id %d",
13919 __func__, pAdapter->sessionId);
13920 return VOS_STATUS_SUCCESS;
13921}
13922
13923/**
13924 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
13925 * @pAdapter: adapter handle
13926 * @mac_addr_in: input mac address
13927 *
13928 * Return: index derived from mac address
13929 */
13930int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
13931 v_MACADDR_t *mac_addr_in)
13932{
13933 uint16 index;
13934 struct hdd_align_mac_addr_t * mac_addr =
13935 (struct hdd_align_mac_addr_t *)mac_addr_in;
13936
13937 index = mac_addr->bytes_ab ^
13938 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
13939 index ^= index >> pAdapter->sta_id_hash.idx_bits;
13940 index &= pAdapter->sta_id_hash.mask;
13941 return index;
13942}
13943
13944/**
13945 * hdd_sta_id_hash_add_entry() - add entry in hash
13946 * @pAdapter: adapter handle
13947 * @sta_id: station id
13948 * @mac_addr: mac address
13949 *
13950 * Return: vos status
13951 */
13952VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
13953 v_U8_t sta_id, v_MACADDR_t *mac_addr)
13954{
13955 uint16 index;
13956 hdd_staid_hash_node_t *sta_info_node = NULL;
13957
Nirav Shah7e3c8132015-06-22 23:51:42 +053013958 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
13959 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
13960 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053013961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13962 "%s: malloc failed", __func__);
13963 return VOS_STATUS_E_NOMEM;
13964 }
13965
13966 sta_info_node->sta_id = sta_id;
13967 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
13968
Nirav Shah303ed5c2015-08-24 10:29:25 +053013969 spin_lock_bh( &pAdapter->sta_hash_lock);
13970 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
13971 spin_unlock_bh( &pAdapter->sta_hash_lock);
13972 vos_mem_free(sta_info_node);
13973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13974 "%s: hash is not initialized for session id %d",
13975 __func__, pAdapter->sessionId);
13976 return VOS_STATUS_E_FAILURE;
13977 }
13978
Nirav Shah7e3c8132015-06-22 23:51:42 +053013979 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
13980 (hdd_list_node_t*) sta_info_node );
13981 spin_unlock_bh( &pAdapter->sta_hash_lock);
13982 return VOS_STATUS_SUCCESS;
13983}
13984
13985/**
13986 * hdd_sta_id_hash_remove_entry() - remove entry from hash
13987 * @pAdapter: adapter handle
13988 * @sta_id: station id
13989 * @mac_addr: mac address
13990 *
13991 * Return: vos status
13992 */
13993VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
13994 v_U8_t sta_id, v_MACADDR_t *mac_addr)
13995{
13996 uint16 index;
13997 VOS_STATUS status;
13998 hdd_staid_hash_node_t *sta_info_node = NULL;
13999 hdd_staid_hash_node_t *next_node = NULL;
14000
14001 spin_lock_bh( &pAdapter->sta_hash_lock);
14002 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14003 spin_unlock_bh( &pAdapter->sta_hash_lock);
14004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14005 "%s: hash is not initialized for session id %d",
14006 __func__, pAdapter->sessionId);
14007 return VOS_STATUS_E_FAILURE;
14008 }
14009
14010 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14011 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14012 (hdd_list_node_t**) &sta_info_node );
14013
14014 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14015 {
14016 if (sta_info_node->sta_id == sta_id) {
14017 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14018 &sta_info_node->node);
14019 vos_mem_free(sta_info_node);
14020 break;
14021 }
14022 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14023 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14024 sta_info_node = next_node;
14025 }
14026 spin_unlock_bh( &pAdapter->sta_hash_lock);
14027 return status;
14028}
14029
14030/**
14031 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14032 * @pAdapter: adapter handle
14033 * @mac_addr_in: mac address
14034 *
14035 * Return: station id
14036 */
14037int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14038 v_MACADDR_t *mac_addr_in)
14039{
14040 uint8 is_found = 0;
14041 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14042 uint16 index;
14043 VOS_STATUS status;
14044 hdd_staid_hash_node_t *sta_info_node = NULL;
14045 hdd_staid_hash_node_t *next_node = NULL;
14046
14047 spin_lock_bh( &pAdapter->sta_hash_lock);
14048 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14049 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014050 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014051 FL("hash is not initialized for session id %d"),
14052 pAdapter->sessionId);
14053 return HDD_WLAN_INVALID_STA_ID;
14054 }
14055
14056 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14057 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14058 (hdd_list_node_t**) &sta_info_node );
14059
14060 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14061 {
14062 if (vos_mem_compare(&sta_info_node->mac_addr,
14063 mac_addr_in, sizeof(v_MACADDR_t))) {
14064 is_found = 1;
14065 sta_id = sta_info_node->sta_id;
14066 break;
14067 }
14068 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14069 (hdd_list_node_t*)sta_info_node,
14070 (hdd_list_node_t**)&next_node);
14071 sta_info_node = next_node;
14072 }
14073 spin_unlock_bh( &pAdapter->sta_hash_lock);
14074 return sta_id;
14075}
14076
c_manjeecfd1efb2015-09-25 19:32:34 +053014077/*FW memory dump feature*/
14078/**
14079 * This structure hold information about the /proc file
14080 *
14081 */
14082static struct proc_dir_entry *proc_file, *proc_dir;
14083
14084/**
14085 * memdump_read() - perform read operation in memory dump proc file
14086 *
14087 * @file - handle for the proc file.
14088 * @buf - pointer to user space buffer.
14089 * @count - number of bytes to be read.
14090 * @pos - offset in the from buffer.
14091 *
14092 * This function performs read operation for the memory dump proc file.
14093 *
14094 * Return: number of bytes read on success, error code otherwise.
14095 */
14096static ssize_t memdump_read(struct file *file, char __user *buf,
14097 size_t count, loff_t *pos)
14098{
14099 int status;
14100 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14101 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014102 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014103 ENTER();
14104
14105 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14106 status = wlan_hdd_validate_context(hdd_ctx);
14107 if (0 != status) {
14108 return -EINVAL;
14109 }
14110
14111 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14112 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14113 return -EINVAL;
14114 }
14115
14116 /* run fs_read_handler in an atomic context*/
14117 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014118 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14119 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014120 {
14121 /*Free the fwr mem dump buffer */
14122 wlan_free_fwr_mem_dump_buffer();
14123 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014124 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014125 }
14126 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14127 vos_ssr_unprotect(__func__);
14128 EXIT();
14129 return ret_count;
14130}
14131
14132/**
14133 * struct memdump_fops - file operations for memory dump feature
14134 * @read - read function for memory dump operation.
14135 *
14136 * This structure initialize the file operation handle for memory
14137 * dump feature
14138 */
14139static const struct file_operations memdump_fops = {
14140 read: memdump_read
14141};
14142
14143/*
14144* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14145* To be passed by HDD to WDA and called upon receiving of response
14146* from firmware
14147* @fwMemDumpReqContext : memory dump request context
14148* @dump_rsp : dump response from HAL
14149* Returns none
14150*/
14151void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14152 tAniFwrDumpRsp *dump_rsp)
14153{
c_manjeef1495642015-10-13 18:35:01 +053014154 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014155
c_manjeef1495642015-10-13 18:35:01 +053014156 ENTER();
14157 spin_lock(&hdd_context_lock);
14158 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14159 spin_unlock(&hdd_context_lock);
14160 return;
14161 }
14162 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014163 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014164 hddLog(LOGE, FL("fw dump request declined by fwr"));
14165 //set the request completion variable
14166 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014167 //Free the allocated fwr dump
14168 wlan_free_fwr_mem_dump_buffer();
14169 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014170 }
c_manjeef1495642015-10-13 18:35:01 +053014171 else {
14172 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14173 /* register the HDD callback which will be called by SVC */
14174 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14175 }
14176 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014177 EXIT();
14178
14179}
14180
14181/**
14182 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14183 *
14184 * This function removes file/dir under proc file system that was
14185 * processing firmware memory dump
14186 *
14187 * Return: None
14188 */
14189static void memdump_procfs_remove(void)
14190{
14191 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14192 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14193 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14194 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14195 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14196}
14197
14198/**
14199 * memdump_procfs_init() - Initialize procfs for memory dump
14200 *
14201 * @vos_ctx - Global vos context.
14202 *
14203 * This function create file under proc file system to be used later for
14204 * processing firmware memory dump
14205 *
14206 * Return: 0 on success, error code otherwise.
14207 */
14208static int memdump_procfs_init(void *vos_ctx)
14209{
14210 hdd_context_t *hdd_ctx;
14211
14212 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14213 if (!hdd_ctx) {
14214 hddLog(LOGE , FL("Invalid HDD context"));
14215 return -EINVAL;
14216 }
14217
14218 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14219 if (proc_dir == NULL) {
14220 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14221 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14222 PROCFS_MEMDUMP_DIR);
14223 return -ENOMEM;
14224 }
14225
14226 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14227 S_IRUSR | S_IWUSR, proc_dir,
14228 &memdump_fops, hdd_ctx);
14229 if (proc_file == NULL) {
14230 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14231 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14232 PROCFS_MEMDUMP_NAME);
14233 return -ENOMEM;
14234 }
14235
14236 hddLog(LOG1 , FL("/proc/%s/%s created"),
14237 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14238
14239 return 0;
14240}
14241
14242/**
14243 * memdump_init() - Initialization function for memory dump feature
14244 *
14245 * This function creates proc file for memdump feature and registers
14246 * HDD callback function with SME.
14247 *
14248 * Return - 0 on success, error otherwise
14249 */
14250int memdump_init(void)
14251{
14252 hdd_context_t *hdd_ctx;
14253 void *vos_ctx;
14254 int status = 0;
14255
14256 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14257 if (!vos_ctx) {
14258 hddLog(LOGE, FL("Invalid VOS context"));
14259 return -EINVAL;
14260 }
14261
14262 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14263 if (!hdd_ctx) {
14264 hddLog(LOGE , FL("Invalid HDD context"));
14265 return -EINVAL;
14266 }
14267
14268 status = memdump_procfs_init(vos_ctx);
14269 if (status) {
14270 hddLog(LOGE , FL("Failed to create proc file"));
14271 return status;
14272 }
14273
14274 return 0;
14275}
14276
14277/**
14278 * memdump_deinit() - De initialize memdump feature
14279 *
14280 * This function removes proc file created for memdump feature.
14281 *
14282 * Return: None
14283 */
14284int memdump_deinit(void)
14285{
14286 hdd_context_t *hdd_ctx;
14287 void *vos_ctx;
14288
14289 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14290 if (!vos_ctx) {
14291 hddLog(LOGE, FL("Invalid VOS context"));
14292 return -EINVAL;
14293 }
14294
14295 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14296 if(!hdd_ctx) {
14297 hddLog(LOGE , FL("Invalid HDD context"));
14298 return -EINVAL;
14299 }
14300
14301 memdump_procfs_remove();
14302 return 0;
14303}
14304
14305/**
14306 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14307 * Return: HAL status
14308 */
14309
14310int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14311{
14312 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014313 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014314 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014315 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014316 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014317
c_manjeecfd1efb2015-09-25 19:32:34 +053014318 /*Check whether a dump request is already going on
14319 *Caution this function will free previously held memory if new dump request is allowed*/
14320 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14321 hddLog(LOGE, FL("Fw memdump already in progress"));
14322 return -EBUSY;
14323 }
14324 //Allocate memory for fw mem dump buffer
14325 ret = wlan_fwr_mem_dump_buffer_allocation();
14326 if(ret == -EFAULT)
14327 {
14328 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14329 return ret;
14330 }
14331 if (0 != ret) {
14332 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14333 return -ENOMEM;
14334 }
c_manjeef1495642015-10-13 18:35:01 +053014335 init_completion(&fw_mem_dump_ctx.req_completion);
14336 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14337 fw_mem_dump_ctx.status = false;
14338
c_manjeecfd1efb2015-09-25 19:32:34 +053014339 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014340 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014341 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14342 if(eHAL_STATUS_SUCCESS != status)
14343 {
14344 hddLog(VOS_TRACE_LEVEL_ERROR,
14345 "%s: fw_mem_dump_req failed ", __func__);
14346 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014347 ret = -EFAULT;
14348 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014349 }
c_manjeef1495642015-10-13 18:35:01 +053014350 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014351 result =
14352 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14353 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14354 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014355 {
14356 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014357 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14358 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014359 }
14360cleanup:
14361 spin_lock(&hdd_context_lock);
14362 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014363 if(!ret && !fw_mem_dump_ctx.status)
14364 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014365 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014366
c_manjeef1495642015-10-13 18:35:01 +053014367 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014368 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014369}
14370
14371/**
14372 * HDD callback which will be called by SVC to indicate mem dump completion.
14373 */
14374void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14375{
14376 if (!pHddFwMemDumpCtx) {
14377 hddLog(VOS_TRACE_LEVEL_ERROR,
14378 "%s: HDD context not valid ", __func__);
14379 return;
14380 }
14381 spin_lock(&hdd_context_lock);
14382 /* check the req magic and set status */
14383 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14384 {
14385 pHddFwMemDumpCtx->status = true;
14386 //signal the completion
14387 complete(&(pHddFwMemDumpCtx->req_completion));
14388 }
14389 else
14390 {
14391 hddLog(VOS_TRACE_LEVEL_ERROR,
14392 "%s: fw mem dump request possible timeout ", __func__);
14393 }
14394 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014395}
14396
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014397void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14398{
14399 if (NULL == pAdapter)
14400 {
14401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14402 return;
14403 }
14404 init_completion(&pAdapter->session_open_comp_var);
14405 init_completion(&pAdapter->session_close_comp_var);
14406 init_completion(&pAdapter->disconnect_comp_var);
14407 init_completion(&pAdapter->linkup_event_var);
14408 init_completion(&pAdapter->cancel_rem_on_chan_var);
14409 init_completion(&pAdapter->rem_on_chan_ready_event);
14410 init_completion(&pAdapter->pno_comp_var);
14411#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14412 init_completion(&pAdapter->offchannel_tx_event);
14413#endif
14414 init_completion(&pAdapter->tx_action_cnf_event);
14415#ifdef FEATURE_WLAN_TDLS
14416 init_completion(&pAdapter->tdls_add_station_comp);
14417 init_completion(&pAdapter->tdls_del_station_comp);
14418 init_completion(&pAdapter->tdls_mgmt_comp);
14419 init_completion(&pAdapter->tdls_link_establish_req_comp);
14420#endif
14421
14422#ifdef WLAN_FEATURE_RMC
14423 init_completion(&pAdapter->ibss_peer_info_comp);
14424#endif /* WLAN_FEATURE_RMC */
14425 init_completion(&pAdapter->ula_complete);
14426 init_completion(&pAdapter->change_country_code);
14427
14428#ifdef FEATURE_WLAN_BATCH_SCAN
14429 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14430 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14431#endif
14432
14433 return;
14434}
c_manjeecfd1efb2015-09-25 19:32:34 +053014435
14436
Jeff Johnson295189b2012-06-20 16:38:30 -070014437//Register the module init/exit functions
14438module_init(hdd_module_init);
14439module_exit(hdd_module_exit);
14440
14441MODULE_LICENSE("Dual BSD/GPL");
14442MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14443MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14444
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014445module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14446 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014447
Jeff Johnson76052702013-04-16 13:55:05 -070014448module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014449 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014450
14451module_param(enable_dfs_chan_scan, int,
14452 S_IRUSR | S_IRGRP | S_IROTH);
14453
14454module_param(enable_11d, int,
14455 S_IRUSR | S_IRGRP | S_IROTH);
14456
14457module_param(country_code, charp,
14458 S_IRUSR | S_IRGRP | S_IROTH);