blob: 53567b9d04c059aff00aec56533f7583ebb0c768 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530210 struct sk_buff *skb
211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
212 , void *accel_priv
213#endif
214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
215 , select_queue_fallback_t fallback
216#endif
217);
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219#ifdef WLAN_FEATURE_PACKET_FILTERING
220static void hdd_set_multicast_list(struct net_device *dev);
221#endif
222
223void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
224
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800225#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
227static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700228static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
229 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
230 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700231static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
232 tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800234#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530235
236/* Store WLAN driver info in a global variable such that crash debugger
237 can extract it from driver debug symbol and crashdump for post processing */
238tANI_U8 g_wlan_driver[ ] = "pronto_driver";
239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800242#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700243
Mihir Shetee1093ba2014-01-21 20:13:32 +0530244static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530245const char * hdd_device_modetoString(v_U8_t device_mode)
246{
247 switch(device_mode)
248 {
249 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
250 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
251 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
252 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
253 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
254 CASE_RETURN_STRING( WLAN_HDD_FTM );
255 CASE_RETURN_STRING( WLAN_HDD_IBSS );
256 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
257 default:
258 return "device_mode Unknown";
259 }
260}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530261
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530262static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 unsigned long state,
264 void *ndev)
265{
266 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#ifdef WLAN_BTAMP_FEATURE
270 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530272 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700276 (strncmp(dev->name, "p2p", 3)))
277 return NOTIFY_DONE;
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 VOS_ASSERT(0);
286 return NOTIFY_DONE;
287 }
288
Jeff Johnson27cee452013-03-27 11:10:24 -0700289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
290 if (NULL == pHddCtx)
291 {
292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
293 VOS_ASSERT(0);
294 return NOTIFY_DONE;
295 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800296 if (pHddCtx->isLogpInProgress)
297 return NOTIFY_DONE;
298
Jeff Johnson27cee452013-03-27 11:10:24 -0700299
300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
301 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
303 switch (state) {
304 case NETDEV_REGISTER:
305 break;
306
307 case NETDEV_UNREGISTER:
308 break;
309
310 case NETDEV_UP:
311 break;
312
313 case NETDEV_DOWN:
314 break;
315
316 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 if(TRUE == pAdapter->isLinkUpSvcNeeded)
318 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 break;
320
321 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530323 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530324 {
325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
326 "%s: Timeout occurred while waiting for abortscan %ld",
327 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 }
329 else
330 {
331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530332 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 }
334#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 status = WLANBAP_StopAmp();
337 if(VOS_STATUS_SUCCESS != status )
338 {
339 pHddCtx->isAmpAllowed = VOS_TRUE;
340 hddLog(VOS_TRACE_LEVEL_FATAL,
341 "%s: Failed to stop AMP", __func__);
342 }
343 else
344 {
345 //a state m/c implementation in PAL is TBD to avoid this delay
346 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700347 if ( pHddCtx->isAmpAllowed )
348 {
349 WLANBAP_DeregisterFromHCI();
350 pHddCtx->isAmpAllowed = VOS_FALSE;
351 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 }
353#endif //WLAN_BTAMP_FEATURE
354 break;
355
356 default:
357 break;
358 }
359
360 return NOTIFY_DONE;
361}
362
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530363static int hdd_netdev_notifier_call(struct notifier_block * nb,
364 unsigned long state,
365 void *ndev)
366{
367 int ret;
368 vos_ssr_protect(__func__);
369 ret = __hdd_netdev_notifier_call( nb, state, ndev);
370 vos_ssr_unprotect(__func__);
371 return ret;
372}
373
Jeff Johnson295189b2012-06-20 16:38:30 -0700374struct notifier_block hdd_netdev_notifier = {
375 .notifier_call = hdd_netdev_notifier_call,
376};
377
378/*---------------------------------------------------------------------------
379 * Function definitions
380 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700381void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
382void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700383//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700384static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700385#ifndef MODULE
386/* current con_mode - used only for statically linked driver
387 * con_mode is changed by userspace to indicate a mode change which will
388 * result in calling the module exit and init functions. The module
389 * exit function will clean up based on the value of con_mode prior to it
390 * being changed by userspace. So curr_con_mode records the current con_mode
391 * for exit when con_mode becomes the next mode for init
392 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700393static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394#endif
395
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530396#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
397/**
398 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
399 * @hdd_ctx: hdd global context
400 *
401 * Return: none
402 */
403static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
404{
405 uint8_t i;
406
407 mutex_init(&hdd_ctx->op_ctx.op_lock);
408 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
409 {
410 hdd_ctx->op_ctx.op_table[i].request_id = 0;
411 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
412 }
413}
414#else
415static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
416{
417}
418#endif
419
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800420/**---------------------------------------------------------------------------
421
422 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
423
424 Called immediately after the cfg.ini is read in order to configure
425 the desired trace levels.
426
427 \param - moduleId - module whose trace level is being configured
428 \param - bitmask - bitmask of log levels to be enabled
429
430 \return - void
431
432 --------------------------------------------------------------------------*/
433static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
434{
435 wpt_tracelevel level;
436
437 /* if the bitmask is the default value, then a bitmask was not
438 specified in cfg.ini, so leave the logging level alone (it
439 will remain at the "compiled in" default value) */
440 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
441 {
442 return;
443 }
444
445 /* a mask was specified. start by disabling all logging */
446 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
447
448 /* now cycle through the bitmask until all "set" bits are serviced */
449 level = VOS_TRACE_LEVEL_FATAL;
450 while (0 != bitmask)
451 {
452 if (bitmask & 1)
453 {
454 vos_trace_setValue(moduleId, level, 1);
455 }
456 level++;
457 bitmask >>= 1;
458 }
459}
460
461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462/**---------------------------------------------------------------------------
463
464 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels in the WDI.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 wpalTraceSetLevel(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
Jeff Johnson295189b2012-06-20 16:38:30 -0700502
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503/*
504 * FUNCTION: wlan_hdd_validate_context
505 * This function is used to check the HDD context
506 */
507int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
508{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530509
510 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
511 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530513 "%s: HDD context is Null", __func__);
514 return -ENODEV;
515 }
516
517 if (pHddCtx->isLogpInProgress)
518 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530520 "%s: LOGP %s. Ignore!!", __func__,
521 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
522 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530523 return -EAGAIN;
524 }
525
Mihir Shete18156292014-03-11 15:38:30 +0530526 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530527 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530529 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
530 return -EAGAIN;
531 }
532 return 0;
533}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700534#ifdef CONFIG_ENABLE_LINUX_REG
535void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
536{
537 hdd_adapter_t *pAdapter = NULL;
538 hdd_station_ctx_t *pHddStaCtx = NULL;
539 eCsrPhyMode phyMode;
540 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530541
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700542 if (NULL == pHddCtx)
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
545 "HDD Context is null !!");
546 return ;
547 }
548
549 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
550 if (NULL == pAdapter)
551 {
552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
553 "pAdapter is null !!");
554 return ;
555 }
556
557 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
558 if (NULL == pHddStaCtx)
559 {
560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
561 "pHddStaCtx is null !!");
562 return ;
563 }
564
565 cfg_param = pHddCtx->cfg_ini;
566 if (NULL == cfg_param)
567 {
568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
569 "cfg_params not available !!");
570 return ;
571 }
572
573 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
574
575 if (!pHddCtx->isVHT80Allowed)
576 {
577 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
578 (eCSR_DOT11_MODE_11ac == phyMode) ||
579 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
580 {
581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
582 "Setting phymode to 11n!!");
583 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
584 }
585 }
586 else
587 {
588 /*New country Supports 11ac as well resetting value back from .ini*/
589 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
590 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
591 return ;
592 }
593
594 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
595 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
596 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
597 {
598 VOS_STATUS vosStatus;
599
600 // need to issue a disconnect to CSR.
601 INIT_COMPLETION(pAdapter->disconnect_comp_var);
602 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
603 pAdapter->sessionId,
604 eCSR_DISCONNECT_REASON_UNSPECIFIED );
605
606 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530607 {
608 long ret;
609
610 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700611 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530612 if (0 >= ret)
613 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
614 ret);
615 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700616
617 }
618}
619#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530620void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
621{
622 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
623 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
624 hdd_config_t *cfg_param;
625 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530626 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530627
628 if (NULL == pHddCtx)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
631 "HDD Context is null !!");
632 return ;
633 }
634
635 cfg_param = pHddCtx->cfg_ini;
636
637 if (NULL == cfg_param)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
640 "cfg_params not available !!");
641 return ;
642 }
643
644 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
645
646 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
647 {
648 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
649 (eCSR_DOT11_MODE_11ac == phyMode) ||
650 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
653 "Setting phymode to 11n!!");
654 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
655 }
656 }
657 else
658 {
659 /*New country Supports 11ac as well resetting value back from .ini*/
660 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
661 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
662 return ;
663 }
664
665 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
666 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
667 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
668 {
669 VOS_STATUS vosStatus;
670
671 // need to issue a disconnect to CSR.
672 INIT_COMPLETION(pAdapter->disconnect_comp_var);
673 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
674 pAdapter->sessionId,
675 eCSR_DISCONNECT_REASON_UNSPECIFIED );
676
677 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530678 {
679 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530680 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530681 if (ret <= 0)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
684 "wait on disconnect_comp_var is failed %ld", ret);
685 }
686 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530687
688 }
689}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700690#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530691
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700692void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
693{
694 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
695 hdd_config_t *cfg_param;
696
697 if (NULL == pHddCtx)
698 {
699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
700 "HDD Context is null !!");
701 return ;
702 }
703
704 cfg_param = pHddCtx->cfg_ini;
705
706 if (NULL == cfg_param)
707 {
708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
709 "cfg_params not available !!");
710 return ;
711 }
712
Agarwal Ashish738843c2014-09-25 12:27:56 +0530713 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
714 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700715 {
716 /*New country doesn't support DFS */
717 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
718 }
719 else
720 {
721 /*New country Supports DFS as well resetting value back from .ini*/
722 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
723 }
724
725}
726
Rajeev79dbe4c2013-10-05 11:03:42 +0530727#ifdef FEATURE_WLAN_BATCH_SCAN
728
729/**---------------------------------------------------------------------------
730
731 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
732 input string
733
734 This function extracts assigned integer from string in below format:
735 "STRING=10" : extracts integer 10 from this string
736
737 \param - pInPtr Pointer to input string
738 \param - base Base for string to int conversion(10 for decimal 16 for hex)
739 \param - pOutPtr Pointer to variable in which extracted integer needs to be
740 assigned
741 \param - pLastArg to tell whether it is last arguement in input string or
742 not
743
744 \return - NULL for failure cases
745 pointer to next arguement in input string for success cases
746 --------------------------------------------------------------------------*/
747static tANI_U8 *
748hdd_extract_assigned_int_from_str
749(
750 tANI_U8 *pInPtr,
751 tANI_U8 base,
752 tANI_U32 *pOutPtr,
753 tANI_U8 *pLastArg
754)
755{
756 int tempInt;
757 int v = 0;
758 char buf[32];
759 int val = 0;
760 *pLastArg = FALSE;
761
762 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
763 if (NULL == pInPtr)
764 {
765 return NULL;
766 }
767
768 pInPtr++;
769
770 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
771
772 val = sscanf(pInPtr, "%32s ", buf);
773 if (val < 0 && val > strlen(pInPtr))
774 {
775 return NULL;
776 }
777 pInPtr += val;
778 v = kstrtos32(buf, base, &tempInt);
779 if (v < 0)
780 {
781 return NULL;
782 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800783 if (tempInt < 0)
784 {
785 tempInt = 0;
786 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530787 *pOutPtr = tempInt;
788
789 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
790 if (NULL == pInPtr)
791 {
792 *pLastArg = TRUE;
793 return NULL;
794 }
795 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
796
797 return pInPtr;
798}
799
800/**---------------------------------------------------------------------------
801
802 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
803 input string
804
805 This function extracts assigned character from string in below format:
806 "STRING=A" : extracts char 'A' from this string
807
808 \param - pInPtr Pointer to input string
809 \param - pOutPtr Pointer to variable in which extracted char needs to be
810 assigned
811 \param - pLastArg to tell whether it is last arguement in input string or
812 not
813
814 \return - NULL for failure cases
815 pointer to next arguement in input string for success cases
816 --------------------------------------------------------------------------*/
817static tANI_U8 *
818hdd_extract_assigned_char_from_str
819(
820 tANI_U8 *pInPtr,
821 tANI_U8 *pOutPtr,
822 tANI_U8 *pLastArg
823)
824{
825 *pLastArg = FALSE;
826
827 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
828 if (NULL == pInPtr)
829 {
830 return NULL;
831 }
832
833 pInPtr++;
834
835 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
836
837 *pOutPtr = *pInPtr;
838
839 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
840 if (NULL == pInPtr)
841 {
842 *pLastArg = TRUE;
843 return NULL;
844 }
845 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
846
847 return pInPtr;
848}
849
850
851/**---------------------------------------------------------------------------
852
853 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
854
855 This function parses set batch scan command in below format:
856 WLS_BATCHING_SET <space> followed by below arguements
857 "SCANFREQ=XX" : Optional defaults to 30 sec
858 "MSCAN=XX" : Required number of scans to attempt to batch
859 "BESTN=XX" : Best Network (RSSI) defaults to 16
860 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
861 A. implies only 5 GHz , B. implies only 2.4GHz
862 "RTT=X" : optional defaults to 0
863 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
864 error
865
866 For example input commands:
867 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
868 translated into set batch scan with following parameters:
869 a) Frequence 60 seconds
870 b) Batch 10 scans together
871 c) Best RSSI to be 20
872 d) 5GHz band only
873 e) RTT is equal to 0
874
875 \param - pValue Pointer to input channel list
876 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
877
878 \return - 0 for success non-zero for failure
879
880 --------------------------------------------------------------------------*/
881static int
882hdd_parse_set_batchscan_command
883(
884 tANI_U8 *pValue,
885 tSirSetBatchScanReq *pHddSetBatchScanReq
886)
887{
888 tANI_U8 *inPtr = pValue;
889 tANI_U8 val = 0;
890 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 tANI_U32 nScanFreq;
892 tANI_U32 nMscan;
893 tANI_U32 nBestN;
894 tANI_U8 ucRfBand;
895 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530897
898 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800899 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
900 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
901 nRtt = 0;
902 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530903
904 /*go to space after WLS_BATCHING_SET command*/
905 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
906 /*no argument after the command*/
907 if (NULL == inPtr)
908 {
909 return -EINVAL;
910 }
911
912 /*no space after the command*/
913 else if (SPACE_ASCII_VALUE != *inPtr)
914 {
915 return -EINVAL;
916 }
917
918 /*removing empty spaces*/
919 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
920
921 /*no argument followed by spaces*/
922 if ('\0' == *inPtr)
923 {
924 return -EINVAL;
925 }
926
927 /*check and parse SCANFREQ*/
928 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
929 {
930 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800935 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800936 }
937
Rajeev79dbe4c2013-10-05 11:03:42 +0530938 if ( (NULL == inPtr) || (TRUE == lastArg))
939 {
940 return -EINVAL;
941 }
942 }
943
944 /*check and parse MSCAN*/
945 if ((strncmp(inPtr, "MSCAN", 5) == 0))
946 {
947 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800948 &nMscan, &lastArg);
949
950 if (0 == nMscan)
951 {
952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
953 "invalid MSCAN=%d", nMscan);
954 return -EINVAL;
955 }
956
Rajeev79dbe4c2013-10-05 11:03:42 +0530957 if (TRUE == lastArg)
958 {
959 goto done;
960 }
961 else if (NULL == inPtr)
962 {
963 return -EINVAL;
964 }
965 }
966 else
967 {
968 return -EINVAL;
969 }
970
971 /*check and parse BESTN*/
972 if ((strncmp(inPtr, "BESTN", 5) == 0))
973 {
974 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800975 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800976
Rajeev Kumarc933d982013-11-18 20:04:20 -0800977 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800978 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800979 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800980 }
981
Rajeev79dbe4c2013-10-05 11:03:42 +0530982 if (TRUE == lastArg)
983 {
984 goto done;
985 }
986 else if (NULL == inPtr)
987 {
988 return -EINVAL;
989 }
990 }
991
992 /*check and parse CHANNEL*/
993 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
994 {
995 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800996
Rajeev79dbe4c2013-10-05 11:03:42 +0530997 if (('A' == val) || ('a' == val))
998 {
c_hpothuebf89732014-02-25 13:00:24 +0530999 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301000 }
1001 else if (('B' == val) || ('b' == val))
1002 {
c_hpothuebf89732014-02-25 13:00:24 +05301003 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301004 }
1005 else
1006 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001007 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1008 }
1009
1010 if (TRUE == lastArg)
1011 {
1012 goto done;
1013 }
1014 else if (NULL == inPtr)
1015 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301016 return -EINVAL;
1017 }
1018 }
1019
1020 /*check and parse RTT*/
1021 if ((strncmp(inPtr, "RTT", 3) == 0))
1022 {
1023 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001024 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301025 if (TRUE == lastArg)
1026 {
1027 goto done;
1028 }
1029 if (NULL == inPtr)
1030 {
1031 return -EINVAL;
1032 }
1033 }
1034
1035
1036done:
1037
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001038 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1039 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1040 pHddSetBatchScanReq->bestNetwork = nBestN;
1041 pHddSetBatchScanReq->rfBand = ucRfBand;
1042 pHddSetBatchScanReq->rtt = nRtt;
1043
Rajeev79dbe4c2013-10-05 11:03:42 +05301044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1045 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1046 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1047 pHddSetBatchScanReq->scanFrequency,
1048 pHddSetBatchScanReq->numberOfScansToBatch,
1049 pHddSetBatchScanReq->bestNetwork,
1050 pHddSetBatchScanReq->rfBand,
1051 pHddSetBatchScanReq->rtt);
1052
1053 return 0;
1054}/*End of hdd_parse_set_batchscan_command*/
1055
1056/**---------------------------------------------------------------------------
1057
1058 \brief hdd_set_batch_scan_req_callback () - This function is called after
1059 receiving set batch scan response from FW and it saves set batch scan
1060 response data FW to HDD context and sets the completion event on
1061 which hdd_ioctl is waiting
1062
1063 \param - callbackContext Pointer to HDD adapter
1064 \param - pRsp Pointer to set batch scan response data received from FW
1065
1066 \return - nothing
1067
1068 --------------------------------------------------------------------------*/
1069static void hdd_set_batch_scan_req_callback
1070(
1071 void *callbackContext,
1072 tSirSetBatchScanRsp *pRsp
1073)
1074{
1075 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1076 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1077
1078 /*sanity check*/
1079 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1080 {
1081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1082 "%s: Invalid pAdapter magic", __func__);
1083 VOS_ASSERT(0);
1084 return;
1085 }
1086 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1087
1088 /*save set batch scan response*/
1089 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1090
1091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1092 "Received set batch scan rsp from FW with nScansToBatch=%d",
1093 pHddSetBatchScanRsp->nScansToBatch);
1094
1095 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1096 complete(&pAdapter->hdd_set_batch_scan_req_var);
1097
1098 return;
1099}/*End of hdd_set_batch_scan_req_callback*/
1100
1101
1102/**---------------------------------------------------------------------------
1103
1104 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1105 info in hdd batch scan response queue
1106
1107 \param - pAdapter Pointer to hdd adapter
1108 \param - pAPMetaInfo Pointer to access point meta info
1109 \param - scanId scan ID of batch scan response
1110 \param - isLastAp tells whether AP is last AP in batch scan response or not
1111
1112 \return - nothing
1113
1114 --------------------------------------------------------------------------*/
1115static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1116 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1117{
1118 tHddBatchScanRsp *pHead;
1119 tHddBatchScanRsp *pNode;
1120 tHddBatchScanRsp *pPrev;
1121 tHddBatchScanRsp *pTemp;
1122 tANI_U8 ssidLen;
1123
1124 /*head of hdd batch scan response queue*/
1125 pHead = pAdapter->pBatchScanRsp;
1126
1127 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1128 if (NULL == pNode)
1129 {
1130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1131 "%s: Could not allocate memory", __func__);
1132 VOS_ASSERT(0);
1133 return;
1134 }
1135
1136 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1137 sizeof(pNode->ApInfo.bssid));
1138 ssidLen = strlen(pApMetaInfo->ssid);
1139 if (SIR_MAX_SSID_SIZE < ssidLen)
1140 {
1141 /*invalid scan result*/
1142 vos_mem_free(pNode);
1143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1144 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1145 return;
1146 }
1147 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1148 /*null terminate ssid*/
1149 pNode->ApInfo.ssid[ssidLen] = '\0';
1150 pNode->ApInfo.ch = pApMetaInfo->ch;
1151 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1152 pNode->ApInfo.age = pApMetaInfo->timestamp;
1153 pNode->ApInfo.batchId = scanId;
1154 pNode->ApInfo.isLastAp = isLastAp;
1155
1156 pNode->pNext = NULL;
1157 if (NULL == pHead)
1158 {
1159 pAdapter->pBatchScanRsp = pNode;
1160 }
1161 else
1162 {
1163 pTemp = pHead;
1164 while (NULL != pTemp)
1165 {
1166 pPrev = pTemp;
1167 pTemp = pTemp->pNext;
1168 }
1169 pPrev->pNext = pNode;
1170 }
1171
1172 return;
1173}/*End of hdd_populate_batch_scan_rsp_queue*/
1174
1175/**---------------------------------------------------------------------------
1176
1177 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1178 receiving batch scan response indication from FW. It saves get batch scan
1179 response data in HDD batch scan response queue. This callback sets the
1180 completion event on which hdd_ioctl is waiting only after getting complete
1181 batch scan response data from FW
1182
1183 \param - callbackContext Pointer to HDD adapter
1184 \param - pRsp Pointer to get batch scan response data received from FW
1185
1186 \return - nothing
1187
1188 --------------------------------------------------------------------------*/
1189static void hdd_batch_scan_result_ind_callback
1190(
1191 void *callbackContext,
1192 void *pRsp
1193)
1194{
1195 v_BOOL_t isLastAp;
1196 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001197 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301198 tANI_U32 numberScanList;
1199 tANI_U32 nextScanListOffset;
1200 tANI_U32 nextApMetaInfoOffset;
1201 hdd_adapter_t* pAdapter;
1202 tpSirBatchScanList pScanList;
1203 tpSirBatchScanNetworkInfo pApMetaInfo;
1204 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1205 tSirSetBatchScanReq *pReq;
1206
1207 pAdapter = (hdd_adapter_t *)callbackContext;
1208 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001209 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: Invalid pAdapter magic", __func__);
1213 VOS_ASSERT(0);
1214 return;
1215 }
1216
1217 /*initialize locals*/
1218 pReq = &pAdapter->hddSetBatchScanReq;
1219 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1220 isLastAp = FALSE;
1221 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001222 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301223 numberScanList = 0;
1224 nextScanListOffset = 0;
1225 nextApMetaInfoOffset = 0;
1226 pScanList = NULL;
1227 pApMetaInfo = NULL;
1228
1229 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1230 {
1231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1232 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1233 isLastAp = TRUE;
1234 goto done;
1235 }
1236
1237 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1239 "Batch scan rsp: numberScalList %d", numberScanList);
1240
1241 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: numberScanList %d", __func__, numberScanList);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248
1249 while (numberScanList)
1250 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001251 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301252 nextScanListOffset);
1253 if (NULL == pScanList)
1254 {
1255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1256 "%s: pScanList is %p", __func__, pScanList);
1257 isLastAp = TRUE;
1258 goto done;
1259 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001260 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001262 "Batch scan rsp: numApMetaInfo %d scanId %d",
1263 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301264
1265 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1266 {
1267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1268 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1269 isLastAp = TRUE;
1270 goto done;
1271 }
1272
Rajeev Kumarce651e42013-10-21 18:57:15 -07001273 /*Initialize next AP meta info offset for next scan list*/
1274 nextApMetaInfoOffset = 0;
1275
Rajeev79dbe4c2013-10-05 11:03:42 +05301276 while (numApMetaInfo)
1277 {
1278 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1279 nextApMetaInfoOffset);
1280 if (NULL == pApMetaInfo)
1281 {
1282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1283 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1284 isLastAp = TRUE;
1285 goto done;
1286 }
1287 /*calculate AP age*/
1288 pApMetaInfo->timestamp =
1289 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1290
1291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001292 "%s: bssId "MAC_ADDRESS_STR
1293 " ch %d rssi %d timestamp %d", __func__,
1294 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1295 pApMetaInfo->ch, pApMetaInfo->rssi,
1296 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301297
1298 /*mark last AP in batch scan response*/
1299 if ((TRUE == pBatchScanRsp->isLastResult) &&
1300 (1 == numberScanList) && (1 == numApMetaInfo))
1301 {
1302 isLastAp = TRUE;
1303 }
1304
1305 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1306 /*store batch scan repsonse in hdd queue*/
1307 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1308 pScanList->scanId, isLastAp);
1309 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1310
1311 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1312 numApMetaInfo--;
1313 }
1314
Rajeev Kumarce651e42013-10-21 18:57:15 -07001315 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1316 + (sizeof(tSirBatchScanNetworkInfo)
1317 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301318 numberScanList--;
1319 }
1320
1321done:
1322
1323 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1324 requested from hdd_ioctl*/
1325 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1326 (TRUE == isLastAp))
1327 {
1328 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1329 complete(&pAdapter->hdd_get_batch_scan_req_var);
1330 }
1331
1332 return;
1333}/*End of hdd_batch_scan_result_ind_callback*/
1334
1335/**---------------------------------------------------------------------------
1336
1337 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1338 response as per batch scan FR request format by putting proper markers
1339
1340 \param - pDest pointer to destination buffer
1341 \param - cur_len current length
1342 \param - tot_len total remaining size which can be written to user space
1343 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1344 \param - pAdapter Pointer to HDD adapter
1345
1346 \return - ret no of characters written
1347
1348 --------------------------------------------------------------------------*/
1349static tANI_U32
1350hdd_format_batch_scan_rsp
1351(
1352 tANI_U8 *pDest,
1353 tANI_U32 cur_len,
1354 tANI_U32 tot_len,
1355 tHddBatchScanRsp *pApMetaInfo,
1356 hdd_adapter_t* pAdapter
1357)
1358{
1359 tANI_U32 ret = 0;
1360 tANI_U32 rem_len = 0;
1361 tANI_U8 temp_len = 0;
1362 tANI_U8 temp_total_len = 0;
1363 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1364 tANI_U8 *pTemp = temp;
1365
1366 /*Batch scan reponse needs to be returned to user space in
1367 following format:
1368 "scancount=X\n" where X is the number of scans in current batch
1369 batch
1370 "trunc\n" optional present if current scan truncated
1371 "bssid=XX:XX:XX:XX:XX:XX\n"
1372 "ssid=XXXX\n"
1373 "freq=X\n" frequency in Mhz
1374 "level=XX\n"
1375 "age=X\n" ms
1376 "dist=X\n" cm (-1 if not available)
1377 "errror=X\n" (-1if not available)
1378 "====\n" (end of ap marker)
1379 "####\n" (end of scan marker)
1380 "----\n" (end of results)*/
1381 /*send scan result in above format to user space based on
1382 available length*/
1383 /*The GET response may have more data than the driver can return in its
1384 buffer. In that case the buffer should be filled to the nearest complete
1385 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1386 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1387 The final buffer should end with "----\n"*/
1388
1389 /*sanity*/
1390 if (cur_len > tot_len)
1391 {
1392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1393 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1394 return 0;
1395 }
1396 else
1397 {
1398 rem_len = (tot_len - cur_len);
1399 }
1400
1401 /*end scan marker*/
1402 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1403 {
1404 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407 }
1408
1409 /*bssid*/
1410 temp_len = snprintf(pTemp, sizeof(temp),
1411 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1412 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1413 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1414 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*ssid*/
1419 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1420 pApMetaInfo->ApInfo.ssid);
1421 pTemp += temp_len;
1422 temp_total_len += temp_len;
1423
1424 /*freq*/
1425 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001426 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301427 pTemp += temp_len;
1428 temp_total_len += temp_len;
1429
1430 /*level*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1432 pApMetaInfo->ApInfo.rssi);
1433 pTemp += temp_len;
1434 temp_total_len += temp_len;
1435
1436 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001437 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 pApMetaInfo->ApInfo.age);
1439 pTemp += temp_len;
1440 temp_total_len += temp_len;
1441
1442 /*dist*/
1443 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1444 pTemp += temp_len;
1445 temp_total_len += temp_len;
1446
1447 /*error*/
1448 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1449 pTemp += temp_len;
1450 temp_total_len += temp_len;
1451
1452 /*end AP marker*/
1453 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1454 pTemp += temp_len;
1455 temp_total_len += temp_len;
1456
1457 /*last AP in batch scan response*/
1458 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1459 {
1460 /*end scan marker*/
1461 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1462 pTemp += temp_len;
1463 temp_total_len += temp_len;
1464
1465 /*end batch scan result marker*/
1466 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1467 pTemp += temp_len;
1468 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001469
Rajeev79dbe4c2013-10-05 11:03:42 +05301470 }
1471
1472 if (temp_total_len < rem_len)
1473 {
1474 ret = temp_total_len + 1;
1475 strlcpy(pDest, temp, ret);
1476 pAdapter->isTruncated = FALSE;
1477 }
1478 else
1479 {
1480 pAdapter->isTruncated = TRUE;
1481 if (rem_len >= strlen("%%%%"))
1482 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001483 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301484 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001485 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 {
1487 ret = 0;
1488 }
1489 }
1490
1491 return ret;
1492
1493}/*End of hdd_format_batch_scan_rsp*/
1494
1495/**---------------------------------------------------------------------------
1496
1497 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1498 buffer starting with head of hdd batch scan response queue
1499
1500 \param - pAdapter Pointer to HDD adapter
1501 \param - pDest Pointer to user data buffer
1502 \param - cur_len current offset in user buffer
1503 \param - rem_len remaining no of bytes in user buffer
1504
1505 \return - number of bytes written in user buffer
1506
1507 --------------------------------------------------------------------------*/
1508
1509tANI_U32 hdd_populate_user_batch_scan_rsp
1510(
1511 hdd_adapter_t* pAdapter,
1512 tANI_U8 *pDest,
1513 tANI_U32 cur_len,
1514 tANI_U32 rem_len
1515)
1516{
1517 tHddBatchScanRsp *pHead;
1518 tHddBatchScanRsp *pPrev;
1519 tANI_U32 len;
1520
Rajeev79dbe4c2013-10-05 11:03:42 +05301521 pAdapter->isTruncated = FALSE;
1522
1523 /*head of hdd batch scan response queue*/
1524 pHead = pAdapter->pBatchScanRsp;
1525 while (pHead)
1526 {
1527 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1528 pAdapter);
1529 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001530 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301531 cur_len += len;
1532 if(TRUE == pAdapter->isTruncated)
1533 {
1534 /*result is truncated return rest of scan rsp in next req*/
1535 cur_len = rem_len;
1536 break;
1537 }
1538 pPrev = pHead;
1539 pHead = pHead->pNext;
1540 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001541 if (TRUE == pPrev->ApInfo.isLastAp)
1542 {
1543 pAdapter->prev_batch_id = 0;
1544 }
1545 else
1546 {
1547 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1548 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301549 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001550 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301551 }
1552
1553 return cur_len;
1554}/*End of hdd_populate_user_batch_scan_rsp*/
1555
1556/**---------------------------------------------------------------------------
1557
1558 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1559 scan response data from HDD queue to user space
1560 It does following in detail:
1561 a) if HDD has enough data in its queue then it 1st copies data to user
1562 space and then send get batch scan indication message to FW. In this
1563 case it does not wait on any event and batch scan response data will
1564 be populated in HDD response queue in MC thread context after receiving
1565 indication from FW
1566 b) else send get batch scan indication message to FW and wait on an event
1567 which will be set once HDD receives complete batch scan response from
1568 FW and then this function returns batch scan response to user space
1569
1570 \param - pAdapter Pointer to HDD adapter
1571 \param - pPrivData Pointer to priv_data
1572
1573 \return - 0 for success -EFAULT for failure
1574
1575 --------------------------------------------------------------------------*/
1576
1577int hdd_return_batch_scan_rsp_to_user
1578(
1579 hdd_adapter_t* pAdapter,
1580 hdd_priv_data_t *pPrivData,
1581 tANI_U8 *command
1582)
1583{
1584 tANI_U8 *pDest;
1585 tANI_U32 count = 0;
1586 tANI_U32 len = 0;
1587 tANI_U32 cur_len = 0;
1588 tANI_U32 rem_len = 0;
1589 eHalStatus halStatus;
1590 unsigned long rc;
1591 tSirTriggerBatchScanResultInd *pReq;
1592
1593 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1594 pReq->param = 0;/*batch scan client*/
1595 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1596 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1597
1598 cur_len = pPrivData->used_len;
1599 if (pPrivData->total_len > pPrivData->used_len)
1600 {
1601 rem_len = pPrivData->total_len - pPrivData->used_len;
1602 }
1603 else
1604 {
1605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1606 "%s: Invalid user data buffer total_len %d used_len %d",
1607 __func__, pPrivData->total_len, pPrivData->used_len);
1608 return -EFAULT;
1609 }
1610
1611 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1612 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1613 cur_len, rem_len);
1614 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1615
1616 /*enough scan result available in cache to return to user space or
1617 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001618 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301619 {
1620 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1621 halStatus = sme_TriggerBatchScanResultInd(
1622 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1623 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1624 pAdapter);
1625 if ( eHAL_STATUS_SUCCESS == halStatus )
1626 {
1627 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1628 {
1629 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1630 rc = wait_for_completion_timeout(
1631 &pAdapter->hdd_get_batch_scan_req_var,
1632 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1633 if (0 == rc)
1634 {
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: Timeout waiting to fetch batch scan rsp from fw",
1637 __func__);
1638 return -EFAULT;
1639 }
1640 }
1641
1642 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001643 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301644 pDest += len;
1645 cur_len += len;
1646
1647 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1648 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1649 cur_len, rem_len);
1650 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1651
1652 count = 0;
1653 len = (len - pPrivData->used_len);
1654 pDest = (command + pPrivData->used_len);
1655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001656 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301657 while(count < len)
1658 {
1659 printk("%c", *(pDest + count));
1660 count++;
1661 }
1662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1663 "%s: copy %d data to user buffer", __func__, len);
1664 if (copy_to_user(pPrivData->buf, pDest, len))
1665 {
1666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1667 "%s: failed to copy data to user buffer", __func__);
1668 return -EFAULT;
1669 }
1670 }
1671 else
1672 {
1673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1674 "sme_GetBatchScanScan returned failure halStatus %d",
1675 halStatus);
1676 return -EINVAL;
1677 }
1678 }
1679 else
1680 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301681 count = 0;
1682 len = (len - pPrivData->used_len);
1683 pDest = (command + pPrivData->used_len);
1684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001685 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301686 while(count < len)
1687 {
1688 printk("%c", *(pDest + count));
1689 count++;
1690 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301693 if (copy_to_user(pPrivData->buf, pDest, len))
1694 {
1695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1696 "%s: failed to copy data to user buffer", __func__);
1697 return -EFAULT;
1698 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301699 }
1700
1701 return 0;
1702} /*End of hdd_return_batch_scan_rsp_to_user*/
1703
Rajeev Kumar8b373292014-01-08 20:36:55 -08001704
1705/**---------------------------------------------------------------------------
1706
1707 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1708 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1709 WLS_BATCHING VERSION
1710 WLS_BATCHING SET
1711 WLS_BATCHING GET
1712 WLS_BATCHING STOP
1713
1714 \param - pAdapter Pointer to HDD adapter
1715 \param - pPrivdata Pointer to priv_data
1716 \param - command Pointer to command
1717
1718 \return - 0 for success -EFAULT for failure
1719
1720 --------------------------------------------------------------------------*/
1721
1722int hdd_handle_batch_scan_ioctl
1723(
1724 hdd_adapter_t *pAdapter,
1725 hdd_priv_data_t *pPrivdata,
1726 tANI_U8 *command
1727)
1728{
1729 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001730 hdd_context_t *pHddCtx;
1731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301732 ENTER();
1733
Yue Mae36e3552014-03-05 17:06:20 -08001734 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1735 ret = wlan_hdd_validate_context(pHddCtx);
1736 if (ret)
1737 {
Yue Mae36e3552014-03-05 17:06:20 -08001738 goto exit;
1739 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001740
1741 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1742 {
1743 char extra[32];
1744 tANI_U8 len = 0;
1745 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1746
1747 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "%s: Batch scan feature is not supported by FW", __func__);
1751 ret = -EINVAL;
1752 goto exit;
1753 }
1754
1755 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1756 version);
1757 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1758 {
1759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1760 "%s: failed to copy data to user buffer", __func__);
1761 ret = -EFAULT;
1762 goto exit;
1763 }
1764 ret = HDD_BATCH_SCAN_VERSION;
1765 }
1766 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1767 {
1768 int status;
1769 tANI_U8 *value = (command + 16);
1770 eHalStatus halStatus;
1771 unsigned long rc;
1772 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1773 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1774
1775 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1776 {
1777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1778 "%s: Batch scan feature is not supported by FW", __func__);
1779 ret = -EINVAL;
1780 goto exit;
1781 }
1782
1783 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1784 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1785 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1786 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1787 {
1788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301789 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001790 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301791 hdd_device_modetoString(pAdapter->device_mode),
1792 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001793 ret = -EINVAL;
1794 goto exit;
1795 }
1796
1797 status = hdd_parse_set_batchscan_command(value, pReq);
1798 if (status)
1799 {
1800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1801 "Invalid WLS_BATCHING SET command");
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805
1806
1807 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1808 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1809 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1810 pAdapter);
1811
1812 if ( eHAL_STATUS_SUCCESS == halStatus )
1813 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301814 char extra[32];
1815 tANI_U8 len = 0;
1816 tANI_U8 mScan = 0;
1817
Rajeev Kumar8b373292014-01-08 20:36:55 -08001818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1819 "sme_SetBatchScanReq returned success halStatus %d",
1820 halStatus);
1821 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1822 {
1823 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1824 rc = wait_for_completion_timeout(
1825 &pAdapter->hdd_set_batch_scan_req_var,
1826 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1827 if (0 == rc)
1828 {
1829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1830 "%s: Timeout waiting for set batch scan to complete",
1831 __func__);
1832 ret = -EINVAL;
1833 goto exit;
1834 }
1835 }
1836 if ( !pRsp->nScansToBatch )
1837 {
1838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1839 "%s: Received set batch scan failure response from FW",
1840 __func__);
1841 ret = -EINVAL;
1842 goto exit;
1843 }
1844 /*As per the Batch Scan Framework API we should return the MIN of
1845 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301846 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001847
1848 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1849
1850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1851 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301852 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1853 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1854 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1855 {
1856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1857 "%s: failed to copy MSCAN value to user buffer", __func__);
1858 ret = -EFAULT;
1859 goto exit;
1860 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001861 }
1862 else
1863 {
1864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1865 "sme_SetBatchScanReq returned failure halStatus %d",
1866 halStatus);
1867 ret = -EINVAL;
1868 goto exit;
1869 }
1870 }
1871 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1872 {
1873 eHalStatus halStatus;
1874 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1875 pInd->param = 0;
1876
1877 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Batch scan feature is not supported by FW", __func__);
1881 ret = -EINVAL;
1882 goto exit;
1883 }
1884
1885 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1886 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001888 "Batch scan is not yet enabled batch scan state %d",
1889 pAdapter->batchScanState);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001894 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1895 hdd_deinit_batch_scan(pAdapter);
1896 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1897
Rajeev Kumar8b373292014-01-08 20:36:55 -08001898 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1899
1900 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1901 pAdapter->sessionId);
1902 if ( eHAL_STATUS_SUCCESS == halStatus )
1903 {
1904 ret = 0;
1905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1906 "sme_StopBatchScanInd returned success halStatus %d",
1907 halStatus);
1908 }
1909 else
1910 {
1911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 "sme_StopBatchScanInd returned failure halStatus %d",
1913 halStatus);
1914 ret = -EINVAL;
1915 goto exit;
1916 }
1917 }
1918 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1919 {
1920 tANI_U32 remain_len;
1921
1922 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1923 {
1924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1925 "%s: Batch scan feature is not supported by FW", __func__);
1926 ret = -EINVAL;
1927 goto exit;
1928 }
1929
1930 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1931 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001933 "Batch scan is not yet enabled could not return results"
1934 "Batch Scan state %d",
1935 pAdapter->batchScanState);
1936 ret = -EINVAL;
1937 goto exit;
1938 }
1939
1940 pPrivdata->used_len = 16;
1941 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1942 if (remain_len < pPrivdata->total_len)
1943 {
1944 /*Clear previous batch scan response data if any*/
1945 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1946 }
1947 else
1948 {
1949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1950 "Invalid total length from user space can't fetch batch"
1951 " scan response total_len %d used_len %d remain len %d",
1952 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1953 ret = -EINVAL;
1954 goto exit;
1955 }
1956 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1957 }
1958
1959exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301960 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001961 return ret;
1962}
1963
1964
Rajeev79dbe4c2013-10-05 11:03:42 +05301965#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1966
c_hpothu92367912014-05-01 15:18:17 +05301967static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1968{
c_hpothu39eb1e32014-06-26 16:31:50 +05301969 bcnMissRateContext_t *pCBCtx;
1970
1971 if (NULL == data)
1972 {
1973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1974 return;
1975 }
c_hpothu92367912014-05-01 15:18:17 +05301976
1977 /* there is a race condition that exists between this callback
1978 function and the caller since the caller could time out either
1979 before or while this code is executing. we use a spinlock to
1980 serialize these actions */
1981 spin_lock(&hdd_context_lock);
1982
c_hpothu39eb1e32014-06-26 16:31:50 +05301983 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301984 gbcnMissRate = -1;
1985
c_hpothu39eb1e32014-06-26 16:31:50 +05301986 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301989 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301990 spin_unlock(&hdd_context_lock);
1991 return ;
1992 }
1993
1994 if (VOS_STATUS_SUCCESS == status)
1995 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301996 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301997 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301998 else
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2001 }
2002
c_hpothu92367912014-05-01 15:18:17 +05302003 complete(&(pCBCtx->completion));
2004 spin_unlock(&hdd_context_lock);
2005
2006 return;
2007}
2008
Abhishek Singh08aa7762014-12-16 13:59:03 +05302009void hdd_FWStatisCB( VOS_STATUS status,
2010 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302011{
2012 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302013 hdd_adapter_t *pAdapter;
2014
2015 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2016
Abhishek Singh08aa7762014-12-16 13:59:03 +05302017 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302018 {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2020 return;
2021 }
2022 /* there is a race condition that exists between this callback
2023 function and the caller since the caller could time out either
2024 before or while this code is executing. we use a spinlock to
2025 serialize these actions */
2026 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302027 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302028 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2029 {
2030 hddLog(VOS_TRACE_LEVEL_ERROR,
2031 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2032 spin_unlock(&hdd_context_lock);
2033 return;
2034 }
2035 pAdapter = fwStatsCtx->pAdapter;
2036 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2037 {
2038 hddLog(VOS_TRACE_LEVEL_ERROR,
2039 FL("pAdapter returned is NULL or invalid"));
2040 spin_unlock(&hdd_context_lock);
2041 return;
2042 }
2043 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302044 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302045 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302046 switch( fwStatsResult->type )
2047 {
2048 case FW_UBSP_STATS:
2049 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302050 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302051 hddLog(VOS_TRACE_LEVEL_INFO,
2052 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302053 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2054 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302055 }
2056 break;
2057 default:
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR,
2060 FL(" No handling for stats type %d"),fwStatsResult->type);
2061 }
2062 }
2063 }
2064 complete(&(fwStatsCtx->completion));
2065 spin_unlock(&hdd_context_lock);
2066 return;
2067}
2068
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302069static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2070{
2071 int ret = 0;
2072
2073 if (!pCfg || !command || !extra || !len)
2074 {
2075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2076 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2077 ret = -EINVAL;
2078 return ret;
2079 }
2080
2081 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2082 {
2083 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2084 (int)pCfg->nActiveMaxChnTime);
2085 return ret;
2086 }
2087 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2088 {
2089 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2090 (int)pCfg->nActiveMinChnTime);
2091 return ret;
2092 }
2093 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2094 {
2095 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2096 (int)pCfg->nPassiveMaxChnTime);
2097 return ret;
2098 }
2099 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2100 {
2101 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2102 (int)pCfg->nPassiveMinChnTime);
2103 return ret;
2104 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302105 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2106 {
2107 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2108 (int)pCfg->nActiveMaxChnTime);
2109 return ret;
2110 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302111 else
2112 {
2113 ret = -EINVAL;
2114 }
2115
2116 return ret;
2117}
2118
2119static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2120{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302122 hdd_config_t *pCfg;
2123 tANI_U8 *value = command;
2124 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302125 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302126
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302127 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2128 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302129 {
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2131 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2132 ret = -EINVAL;
2133 return ret;
2134 }
2135
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302136 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2137 sme_GetConfigParam(hHal, &smeConfig);
2138
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2140 {
2141 value = value + 24;
2142 temp = kstrtou32(value, 10, &val);
2143 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2144 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2145 {
2146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2147 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2148 ret = -EFAULT;
2149 return ret;
2150 }
2151 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302152 smeConfig.csrConfig.nActiveMaxChnTime = val;
2153 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302154 }
2155 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2156 {
2157 value = value + 24;
2158 temp = kstrtou32(value, 10, &val);
2159 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2160 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2161 {
2162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2163 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2164 ret = -EFAULT;
2165 return ret;
2166 }
2167 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302168 smeConfig.csrConfig.nActiveMinChnTime = val;
2169 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302170 }
2171 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2172 {
2173 value = value + 25;
2174 temp = kstrtou32(value, 10, &val);
2175 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2176 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2179 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2180 ret = -EFAULT;
2181 return ret;
2182 }
2183 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302184 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2185 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302186 }
2187 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2188 {
2189 value = value + 25;
2190 temp = kstrtou32(value, 10, &val);
2191 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2192 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2193 {
2194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2195 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2196 ret = -EFAULT;
2197 return ret;
2198 }
2199 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302200 smeConfig.csrConfig.nPassiveMinChnTime = val;
2201 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302202 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302203 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2204 {
2205 value = value + 13;
2206 temp = kstrtou32(value, 10, &val);
2207 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2208 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2209 {
2210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2211 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2212 ret = -EFAULT;
2213 return ret;
2214 }
2215 pCfg->nActiveMaxChnTime = val;
2216 smeConfig.csrConfig.nActiveMaxChnTime = val;
2217 sme_UpdateConfig(hHal, &smeConfig);
2218 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302219 else
2220 {
2221 ret = -EINVAL;
2222 }
2223
2224 return ret;
2225}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302226static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2227 tANI_U8 cmd_len)
2228{
2229 tANI_U8 *value;
2230 tANI_U8 fcc_constraint;
2231
2232 eHalStatus status;
2233 int ret = 0;
2234 value = cmd + cmd_len + 1;
2235
2236 ret = kstrtou8(value, 10, &fcc_constraint);
2237 if ((ret < 0) || (fcc_constraint > 1)) {
2238 /*
2239 * If the input value is greater than max value of datatype,
2240 * then also it is a failure
2241 */
2242 hddLog(VOS_TRACE_LEVEL_ERROR,
2243 "%s: value out of range", __func__);
2244 return -EINVAL;
2245 }
2246
2247 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2248 if (status != eHAL_STATUS_SUCCESS)
2249 ret = -EPERM;
2250
2251 return ret;
2252}
2253
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302254/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302255
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302256 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2257 FW will send *ONE* CA ind to Host(even though it is duplicate).
2258 When Host send IOCTL (disable), FW doesn't perform any action.
2259 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2260 sends CA ind to host. (regard less of IOCTL status)
2261 \param - pHddCtx - HDD context
2262 \param - command - command received from framework
2263 \param - cmd_len - len of the command
2264
2265 \return - 0 on success, appropriate error values on failure.
2266
2267 --------------------------------------------------------------------------*/
2268int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2269{
2270 tANI_U8 set_value;
2271 int ret = 0;
2272 eHalStatus status;
2273
2274 ret = wlan_hdd_validate_context(pHddCtx);
2275 if (0 != ret)
2276 {
2277 ret = -EINVAL;
2278 goto exit;
2279 }
2280
2281 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2282 {
2283 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2284 " ini param to control channel avooidance indication");
2285 ret = 0;
2286 goto exit;
2287 }
2288
2289 set_value = command[cmd_len + 1] - '0';
2290 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2291 if (status != eHAL_STATUS_SUCCESS)
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2294 " enableDisableChanAoidance command to SME\n", __func__);
2295 ret = -EINVAL;
2296 }
2297
2298exit:
2299 return ret;
2300}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302301
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002302static int hdd_driver_command(hdd_adapter_t *pAdapter,
2303 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304{
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 hdd_priv_data_t priv_data;
2306 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302307 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2308 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002309 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302310 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2312 struct cfg80211_mgmt_tx_params params;
2313#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302314
2315 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002316 /*
2317 * Note that valid pointers are provided by caller
2318 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002319
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002320 /* copy to local struct to avoid numerous changes to legacy code */
2321 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002322
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002323 if (priv_data.total_len <= 0 ||
2324 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002325 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002326 hddLog(VOS_TRACE_LEVEL_WARN,
2327 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2328 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002329 ret = -EINVAL;
2330 goto exit;
2331 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302332 status = wlan_hdd_validate_context(pHddCtx);
2333 if (0 != status)
2334 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302335 ret = -EINVAL;
2336 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302337 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002338 /* Allocate +1 for '\0' */
2339 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 if (!command)
2341 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002342 hddLog(VOS_TRACE_LEVEL_ERROR,
2343 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 ret = -ENOMEM;
2345 goto exit;
2346 }
2347
2348 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2349 {
2350 ret = -EFAULT;
2351 goto exit;
2352 }
2353
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002354 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002355 command[priv_data.total_len] = '\0';
2356
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002357 /* at one time the following block of code was conditional. braces
2358 * have been retained to avoid re-indenting the legacy code
2359 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 {
2361 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2362
2363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002364 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002365
2366 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2367 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2369 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2370 pAdapter->sessionId, (unsigned)
2371 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2372 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2373 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2374 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2376 sizeof(tSirMacAddr)))
2377 {
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002379 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002380 ret = -EFAULT;
2381 }
2382 }
Amar Singhal0974e402013-02-12 14:27:46 -08002383 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 {
Amar Singhal0974e402013-02-12 14:27:46 -08002385 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002386
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388
2389 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002392 "%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 +05302393 if(VOS_FTM_MODE != hdd_get_conparam())
2394 {
2395 /* Change band request received */
2396 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2397 if(ret < 0)
2398 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2399 "%s: failed to set band ret=%d", __func__, ret);
2400 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002401 }
Kiet Lamf040f472013-11-20 21:15:23 +05302402 else if(strncmp(command, "SETWMMPS", 8) == 0)
2403 {
2404 tANI_U8 *ptr = command;
2405 ret = hdd_wmmps_helper(pAdapter, ptr);
2406 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302407
2408 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2409 {
2410 tANI_U8 *ptr = command;
2411 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2412 }
2413
Jeff Johnson32d95a32012-09-10 13:15:23 -07002414 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2415 {
2416 char *country_code;
2417
2418 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002419
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002420 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002421 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002422#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302423 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002424#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002425 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2426 (void *)(tSmeChangeCountryCallback)
2427 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302428 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002429 if (eHAL_STATUS_SUCCESS == ret)
2430 {
2431 ret = wait_for_completion_interruptible_timeout(
2432 &pAdapter->change_country_code,
2433 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2434 if (0 >= ret)
2435 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302437 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002438 }
2439 }
2440 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002441 {
2442 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002443 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002444 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002445 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002446
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002447 }
2448 /*
2449 command should be a string having format
2450 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2451 */
Amar Singhal0974e402013-02-12 14:27:46 -08002452 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002453 {
Amar Singhal0974e402013-02-12 14:27:46 -08002454 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002455
2456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002457 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002458
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002459 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002460 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002461 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2462 {
2463 int suspend = 0;
2464 tANI_U8 *ptr = (tANI_U8*)command + 15;
2465
2466 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2468 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2469 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002470 hdd_set_wlan_suspend_mode(suspend);
2471 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002472#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2473 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2474 {
2475 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002476 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002477 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2478 eHalStatus status = eHAL_STATUS_SUCCESS;
2479
2480 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2481 value = value + 15;
2482
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002483 /* Convert the value from ascii to integer */
2484 ret = kstrtos8(value, 10, &rssi);
2485 if (ret < 0)
2486 {
2487 /* If the input value is greater than max value of datatype, then also
2488 kstrtou8 fails */
2489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2490 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002491 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2493 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2494 ret = -EINVAL;
2495 goto exit;
2496 }
2497
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002499
Srinivas Girigowdade697412013-02-14 16:31:48 -08002500 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2501 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2502 {
2503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2504 "Neighbor lookup threshold value %d is out of range"
2505 " (Min: %d Max: %d)", lookUpThreshold,
2506 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2507 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2508 ret = -EINVAL;
2509 goto exit;
2510 }
2511
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302512 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2513 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2514 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2516 "%s: Received Command to Set Roam trigger"
2517 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2518
2519 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2520 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2521 if (eHAL_STATUS_SUCCESS != status)
2522 {
2523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2524 "%s: Failed to set roam trigger, try again", __func__);
2525 ret = -EPERM;
2526 goto exit;
2527 }
2528
2529 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302530 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002531 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2532 }
2533 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2534 {
2535 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2536 int rssi = (-1) * lookUpThreshold;
2537 char extra[32];
2538 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2540 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2541 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002542 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302543 len = VOS_MIN(priv_data.total_len, len + 1);
2544 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002545 {
2546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2547 "%s: failed to copy data to user buffer", __func__);
2548 ret = -EFAULT;
2549 goto exit;
2550 }
2551 }
2552 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2553 {
2554 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002555 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002556 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002557
Srinivas Girigowdade697412013-02-14 16:31:48 -08002558 /* input refresh period is in terms of seconds */
2559 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2560 value = value + 18;
2561 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002562 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002563 if (ret < 0)
2564 {
2565 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002566 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002568 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002569 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002570 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2571 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002572 ret = -EINVAL;
2573 goto exit;
2574 }
2575
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002576 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2577 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002580 "Roam scan period value %d is out of range"
2581 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002582 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2583 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002584 ret = -EINVAL;
2585 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302586 }
2587 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2588 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2589 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002590 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002591
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2593 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002594 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002596 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2597 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002598 }
2599 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2600 {
2601 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2602 char extra[32];
2603 tANI_U8 len = 0;
2604
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302605 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2606 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2607 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002608 len = scnprintf(extra, sizeof(extra), "%s %d",
2609 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002610 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05302611 len = VOS_MIN(priv_data.total_len, len + 1);
2612 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2614 "%s: failed to copy data to user buffer", __func__);
2615 ret = -EFAULT;
2616 goto exit;
2617 }
2618 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002619 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2620 {
2621 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002622 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002623 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002624
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002625 /* input refresh period is in terms of seconds */
2626 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2627 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002628
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002629 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002630 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002631 if (ret < 0)
2632 {
2633 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002634 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002636 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002637 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002638 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2639 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2640 ret = -EINVAL;
2641 goto exit;
2642 }
2643
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002644 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2645 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2646 {
2647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2648 "Neighbor scan results refresh period value %d is out of range"
2649 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2650 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2651 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2652 ret = -EINVAL;
2653 goto exit;
2654 }
2655 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2656
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2658 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002659 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002660
2661 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2662 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2663 }
2664 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2665 {
2666 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2667 char extra[32];
2668 tANI_U8 len = 0;
2669
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002670 len = scnprintf(extra, sizeof(extra), "%s %d",
2671 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002672 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05302673 len = VOS_MIN(priv_data.total_len, len + 1);
2674 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 "%s: failed to copy data to user buffer", __func__);
2677 ret = -EFAULT;
2678 goto exit;
2679 }
2680 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002681#ifdef FEATURE_WLAN_LFR
2682 /* SETROAMMODE */
2683 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2684 {
2685 tANI_U8 *value = command;
2686 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2687
2688 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2689 value = value + SIZE_OF_SETROAMMODE + 1;
2690
2691 /* Convert the value from ascii to integer */
2692 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2693 if (ret < 0)
2694 {
2695 /* If the input value is greater than max value of datatype, then also
2696 kstrtou8 fails */
2697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2698 "%s: kstrtou8 failed range [%d - %d]", __func__,
2699 CFG_LFR_FEATURE_ENABLED_MIN,
2700 CFG_LFR_FEATURE_ENABLED_MAX);
2701 ret = -EINVAL;
2702 goto exit;
2703 }
2704 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2705 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2706 {
2707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2708 "Roam Mode value %d is out of range"
2709 " (Min: %d Max: %d)", roamMode,
2710 CFG_LFR_FEATURE_ENABLED_MIN,
2711 CFG_LFR_FEATURE_ENABLED_MAX);
2712 ret = -EINVAL;
2713 goto exit;
2714 }
2715
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2717 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2718 /*
2719 * Note that
2720 * SETROAMMODE 0 is to enable LFR while
2721 * SETROAMMODE 1 is to disable LFR, but
2722 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2723 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2724 */
2725 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2726 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2727 else
2728 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2729
2730 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2731 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2732 }
2733 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302734 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002735 {
2736 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2737 char extra[32];
2738 tANI_U8 len = 0;
2739
2740 /*
2741 * roamMode value shall be inverted because the sementics is different.
2742 */
2743 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2744 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2745 else
2746 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2747
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002748 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05302749 len = VOS_MIN(priv_data.total_len, len + 1);
2750 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2752 "%s: failed to copy data to user buffer", __func__);
2753 ret = -EFAULT;
2754 goto exit;
2755 }
2756 }
2757#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002758#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002759#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002760 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2761 {
2762 tANI_U8 *value = command;
2763 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2764
2765 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2766 value = value + 13;
2767 /* Convert the value from ascii to integer */
2768 ret = kstrtou8(value, 10, &roamRssiDiff);
2769 if (ret < 0)
2770 {
2771 /* If the input value is greater than max value of datatype, then also
2772 kstrtou8 fails */
2773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2774 "%s: kstrtou8 failed range [%d - %d]", __func__,
2775 CFG_ROAM_RSSI_DIFF_MIN,
2776 CFG_ROAM_RSSI_DIFF_MAX);
2777 ret = -EINVAL;
2778 goto exit;
2779 }
2780
2781 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2782 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2783 {
2784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2785 "Roam rssi diff value %d is out of range"
2786 " (Min: %d Max: %d)", roamRssiDiff,
2787 CFG_ROAM_RSSI_DIFF_MIN,
2788 CFG_ROAM_RSSI_DIFF_MAX);
2789 ret = -EINVAL;
2790 goto exit;
2791 }
2792
2793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2794 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2795
2796 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2797 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2798 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302799 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002800 {
2801 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2802 char extra[32];
2803 tANI_U8 len = 0;
2804
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302805 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2806 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2807 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002808 len = scnprintf(extra, sizeof(extra), "%s %d",
2809 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05302810 len = VOS_MIN(priv_data.total_len, len + 1);
2811 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2813 "%s: failed to copy data to user buffer", __func__);
2814 ret = -EFAULT;
2815 goto exit;
2816 }
2817 }
2818#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002819#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002820 else if (strncmp(command, "GETBAND", 7) == 0)
2821 {
2822 int band = -1;
2823 char extra[32];
2824 tANI_U8 len = 0;
2825 hdd_getBand_helper(pHddCtx, &band);
2826
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2828 TRACE_CODE_HDD_GETBAND_IOCTL,
2829 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002830 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05302831 len = VOS_MIN(priv_data.total_len, len + 1);
2832 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2834 "%s: failed to copy data to user buffer", __func__);
2835 ret = -EFAULT;
2836 goto exit;
2837 }
2838 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002839 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2840 {
2841 tANI_U8 *value = command;
2842 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2843 tANI_U8 numChannels = 0;
2844 eHalStatus status = eHAL_STATUS_SUCCESS;
2845
2846 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2847 if (eHAL_STATUS_SUCCESS != status)
2848 {
2849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2850 "%s: Failed to parse channel list information", __func__);
2851 ret = -EINVAL;
2852 goto exit;
2853 }
2854
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302855 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2856 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2857 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002858 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2859 {
2860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2861 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2862 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2863 ret = -EINVAL;
2864 goto exit;
2865 }
2866 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2867 numChannels);
2868 if (eHAL_STATUS_SUCCESS != status)
2869 {
2870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2871 "%s: Failed to update channel list information", __func__);
2872 ret = -EINVAL;
2873 goto exit;
2874 }
2875 }
2876 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2877 {
2878 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2879 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002880 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002881 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002882 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002883
2884 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2885 ChannelList, &numChannels ))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2888 "%s: failed to get roam scan channel list", __func__);
2889 ret = -EFAULT;
2890 goto exit;
2891 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302892 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2893 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2894 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002895 /* output channel list is of the format
2896 [Number of roam scan channels][Channel1][Channel2]... */
2897 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002898 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05302899 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002900 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002901 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2902 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002903 }
2904
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302905 len = VOS_MIN(priv_data.total_len, len + 1);
2906 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002907 {
2908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2909 "%s: failed to copy data to user buffer", __func__);
2910 ret = -EFAULT;
2911 goto exit;
2912 }
2913 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002914 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2915 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002916 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002917 char extra[32];
2918 tANI_U8 len = 0;
2919
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002920 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002921 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002922 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002923 hdd_is_okc_mode_enabled(pHddCtx) &&
2924 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2925 {
2926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002927 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002928 " hence this operation is not permitted!", __func__);
2929 ret = -EPERM;
2930 goto exit;
2931 }
2932
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002933 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002934 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302935 len = VOS_MIN(priv_data.total_len, len + 1);
2936 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002937 {
2938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2939 "%s: failed to copy data to user buffer", __func__);
2940 ret = -EFAULT;
2941 goto exit;
2942 }
2943 }
2944 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2945 {
2946 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2947 char extra[32];
2948 tANI_U8 len = 0;
2949
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002950 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002951 then this operation is not permitted (return FAILURE) */
2952 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002953 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002954 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2955 {
2956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002957 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002958 " hence this operation is not permitted!", __func__);
2959 ret = -EPERM;
2960 goto exit;
2961 }
2962
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002963 len = scnprintf(extra, sizeof(extra), "%s %d",
2964 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302965 len = VOS_MIN(priv_data.total_len, len + 1);
2966 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002967 {
2968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2969 "%s: failed to copy data to user buffer", __func__);
2970 ret = -EFAULT;
2971 goto exit;
2972 }
2973 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002974 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002975 {
2976 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2977 char extra[32];
2978 tANI_U8 len = 0;
2979
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002980 len = scnprintf(extra, sizeof(extra), "%s %d",
2981 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302982 len = VOS_MIN(priv_data.total_len, len + 1);
2983 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002984 {
2985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2986 "%s: failed to copy data to user buffer", __func__);
2987 ret = -EFAULT;
2988 goto exit;
2989 }
2990 }
2991 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2992 {
2993 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2994 char extra[32];
2995 tANI_U8 len = 0;
2996
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002997 len = scnprintf(extra, sizeof(extra), "%s %d",
2998 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302999 len = VOS_MIN(priv_data.total_len, len + 1);
3000 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003001 {
3002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3003 "%s: failed to copy data to user buffer", __func__);
3004 ret = -EFAULT;
3005 goto exit;
3006 }
3007 }
3008 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3009 {
3010 tANI_U8 *value = command;
3011 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3012
3013 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3014 value = value + 26;
3015 /* Convert the value from ascii to integer */
3016 ret = kstrtou8(value, 10, &minTime);
3017 if (ret < 0)
3018 {
3019 /* If the input value is greater than max value of datatype, then also
3020 kstrtou8 fails */
3021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3022 "%s: kstrtou8 failed range [%d - %d]", __func__,
3023 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3024 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3025 ret = -EINVAL;
3026 goto exit;
3027 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003028 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3029 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3030 {
3031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3032 "scan min channel time value %d is out of range"
3033 " (Min: %d Max: %d)", minTime,
3034 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3035 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3036 ret = -EINVAL;
3037 goto exit;
3038 }
3039
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303040 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3041 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3042 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3044 "%s: Received Command to change channel min time = %d", __func__, minTime);
3045
3046 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3047 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3048 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003049 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3050 {
3051 tANI_U8 *value = command;
3052 tANI_U8 channel = 0;
3053 tANI_U8 dwellTime = 0;
3054 tANI_U8 bufLen = 0;
3055 tANI_U8 *buf = NULL;
3056 tSirMacAddr targetApBssid;
3057 eHalStatus status = eHAL_STATUS_SUCCESS;
3058 struct ieee80211_channel chan;
3059 tANI_U8 finalLen = 0;
3060 tANI_U8 *finalBuf = NULL;
3061 tANI_U8 temp = 0;
3062 u64 cookie;
3063 hdd_station_ctx_t *pHddStaCtx = NULL;
3064 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3065
3066 /* if not associated, no need to send action frame */
3067 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3068 {
3069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3070 ret = -EINVAL;
3071 goto exit;
3072 }
3073
3074 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3075 &dwellTime, &buf, &bufLen);
3076 if (eHAL_STATUS_SUCCESS != status)
3077 {
3078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3079 "%s: Failed to parse send action frame data", __func__);
3080 ret = -EINVAL;
3081 goto exit;
3082 }
3083
3084 /* if the target bssid is different from currently associated AP,
3085 then no need to send action frame */
3086 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3087 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3088 {
3089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3090 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003091 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003092 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003093 goto exit;
3094 }
3095
3096 /* if the channel number is different from operating channel then
3097 no need to send action frame */
3098 if (channel != pHddStaCtx->conn_info.operationChannel)
3099 {
3100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3101 "%s: channel(%d) is different from operating channel(%d)",
3102 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3103 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003104 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003105 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003106 goto exit;
3107 }
3108 chan.center_freq = sme_ChnToFreq(channel);
3109
3110 finalLen = bufLen + 24;
3111 finalBuf = vos_mem_malloc(finalLen);
3112 if (NULL == finalBuf)
3113 {
3114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3115 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003116 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003117 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003118 goto exit;
3119 }
3120 vos_mem_zero(finalBuf, finalLen);
3121
3122 /* Fill subtype */
3123 temp = SIR_MAC_MGMT_ACTION << 4;
3124 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3125
3126 /* Fill type */
3127 temp = SIR_MAC_MGMT_FRAME;
3128 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3129
3130 /* Fill destination address (bssid of the AP) */
3131 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3132
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003133 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003134 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3135
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003136 /* Fill BSSID (AP mac address) */
3137 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003138
3139 /* Fill received buffer from 24th address */
3140 vos_mem_copy(finalBuf + 24, buf, bufLen);
3141
Jeff Johnson11c33152013-04-16 17:52:40 -07003142 /* done with the parsed buffer */
3143 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003144 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003145
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3147 params.chan = &chan;
3148 params.offchan = 0;
3149 params.wait = dwellTime;
3150 params.buf = finalBuf;
3151 params.len = finalLen;
3152 params.no_cck = 1;
3153 params.dont_wait_for_ack = 1;
3154 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3155#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303156 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3158 &(pAdapter->wdev),
3159#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003160 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003161#endif
3162 &chan, 0,
3163#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3164 NL80211_CHAN_HT20, 1,
3165#endif
3166 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003167 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303168#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003169 vos_mem_free(finalBuf);
3170 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003171 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3172 {
3173 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3174 char extra[32];
3175 tANI_U8 len = 0;
3176
3177 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003178 len = scnprintf(extra, sizeof(extra), "%s %d",
3179 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3181 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3182 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303183 len = VOS_MIN(priv_data.total_len, len + 1);
3184 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003185 {
3186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3187 "%s: failed to copy data to user buffer", __func__);
3188 ret = -EFAULT;
3189 goto exit;
3190 }
3191 }
3192 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3193 {
3194 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003195 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003196
3197 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3198 value = value + 19;
3199 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003200 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003201 if (ret < 0)
3202 {
3203 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003204 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003206 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003207 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3208 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3209 ret = -EINVAL;
3210 goto exit;
3211 }
3212
3213 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3214 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3215 {
3216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3217 "lfr mode value %d is out of range"
3218 " (Min: %d Max: %d)", maxTime,
3219 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3220 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3221 ret = -EINVAL;
3222 goto exit;
3223 }
3224
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3226 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3227
3228 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3229 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3230 }
3231 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3232 {
3233 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3234 char extra[32];
3235 tANI_U8 len = 0;
3236
3237 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003238 len = scnprintf(extra, sizeof(extra), "%s %d",
3239 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303240 len = VOS_MIN(priv_data.total_len, len + 1);
3241 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003242 {
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3244 "%s: failed to copy data to user buffer", __func__);
3245 ret = -EFAULT;
3246 goto exit;
3247 }
3248 }
3249 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3250 {
3251 tANI_U8 *value = command;
3252 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3253
3254 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3255 value = value + 16;
3256 /* Convert the value from ascii to integer */
3257 ret = kstrtou16(value, 10, &val);
3258 if (ret < 0)
3259 {
3260 /* If the input value is greater than max value of datatype, then also
3261 kstrtou16 fails */
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "%s: kstrtou16 failed range [%d - %d]", __func__,
3264 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3265 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3266 ret = -EINVAL;
3267 goto exit;
3268 }
3269
3270 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3271 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3272 {
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3274 "scan home time value %d is out of range"
3275 " (Min: %d Max: %d)", val,
3276 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3277 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3278 ret = -EINVAL;
3279 goto exit;
3280 }
3281
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3283 "%s: Received Command to change scan home time = %d", __func__, val);
3284
3285 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3286 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3287 }
3288 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3289 {
3290 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3291 char extra[32];
3292 tANI_U8 len = 0;
3293
3294 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003295 len = scnprintf(extra, sizeof(extra), "%s %d",
3296 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303297 len = VOS_MIN(priv_data.total_len, len + 1);
3298 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003299 {
3300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3301 "%s: failed to copy data to user buffer", __func__);
3302 ret = -EFAULT;
3303 goto exit;
3304 }
3305 }
3306 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3307 {
3308 tANI_U8 *value = command;
3309 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3310
3311 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3312 value = value + 17;
3313 /* Convert the value from ascii to integer */
3314 ret = kstrtou8(value, 10, &val);
3315 if (ret < 0)
3316 {
3317 /* If the input value is greater than max value of datatype, then also
3318 kstrtou8 fails */
3319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: kstrtou8 failed range [%d - %d]", __func__,
3321 CFG_ROAM_INTRA_BAND_MIN,
3322 CFG_ROAM_INTRA_BAND_MAX);
3323 ret = -EINVAL;
3324 goto exit;
3325 }
3326
3327 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3328 (val > CFG_ROAM_INTRA_BAND_MAX))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "intra band mode value %d is out of range"
3332 " (Min: %d Max: %d)", val,
3333 CFG_ROAM_INTRA_BAND_MIN,
3334 CFG_ROAM_INTRA_BAND_MAX);
3335 ret = -EINVAL;
3336 goto exit;
3337 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3339 "%s: Received Command to change intra band = %d", __func__, val);
3340
3341 pHddCtx->cfg_ini->nRoamIntraBand = val;
3342 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3343 }
3344 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3345 {
3346 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3347 char extra[32];
3348 tANI_U8 len = 0;
3349
3350 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003351 len = scnprintf(extra, sizeof(extra), "%s %d",
3352 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303353 len = VOS_MIN(priv_data.total_len, len + 1);
3354 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003355 {
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3357 "%s: failed to copy data to user buffer", __func__);
3358 ret = -EFAULT;
3359 goto exit;
3360 }
3361 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003362 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3363 {
3364 tANI_U8 *value = command;
3365 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3366
3367 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3368 value = value + 15;
3369 /* Convert the value from ascii to integer */
3370 ret = kstrtou8(value, 10, &nProbes);
3371 if (ret < 0)
3372 {
3373 /* If the input value is greater than max value of datatype, then also
3374 kstrtou8 fails */
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3376 "%s: kstrtou8 failed range [%d - %d]", __func__,
3377 CFG_ROAM_SCAN_N_PROBES_MIN,
3378 CFG_ROAM_SCAN_N_PROBES_MAX);
3379 ret = -EINVAL;
3380 goto exit;
3381 }
3382
3383 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3384 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3385 {
3386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3387 "NProbes value %d is out of range"
3388 " (Min: %d Max: %d)", nProbes,
3389 CFG_ROAM_SCAN_N_PROBES_MIN,
3390 CFG_ROAM_SCAN_N_PROBES_MAX);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3396 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3397
3398 pHddCtx->cfg_ini->nProbes = nProbes;
3399 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3400 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303401 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003402 {
3403 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3404 char extra[32];
3405 tANI_U8 len = 0;
3406
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003407 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05303408 len = VOS_MIN(priv_data.total_len, len + 1);
3409 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3411 "%s: failed to copy data to user buffer", __func__);
3412 ret = -EFAULT;
3413 goto exit;
3414 }
3415 }
3416 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3417 {
3418 tANI_U8 *value = command;
3419 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3420
3421 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3422 /* input value is in units of msec */
3423 value = value + 20;
3424 /* Convert the value from ascii to integer */
3425 ret = kstrtou16(value, 10, &homeAwayTime);
3426 if (ret < 0)
3427 {
3428 /* If the input value is greater than max value of datatype, then also
3429 kstrtou8 fails */
3430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3431 "%s: kstrtou8 failed range [%d - %d]", __func__,
3432 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3433 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3434 ret = -EINVAL;
3435 goto exit;
3436 }
3437
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003438 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3439 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3440 {
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3442 "homeAwayTime value %d is out of range"
3443 " (Min: %d Max: %d)", homeAwayTime,
3444 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3445 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3446 ret = -EINVAL;
3447 goto exit;
3448 }
3449
3450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3451 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003452 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3453 {
3454 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3455 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3456 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003457 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303458 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003459 {
3460 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3461 char extra[32];
3462 tANI_U8 len = 0;
3463
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003464 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05303465 len = VOS_MIN(priv_data.total_len, len + 1);
3466 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3468 "%s: failed to copy data to user buffer", __func__);
3469 ret = -EFAULT;
3470 goto exit;
3471 }
3472 }
3473 else if (strncmp(command, "REASSOC", 7) == 0)
3474 {
3475 tANI_U8 *value = command;
3476 tANI_U8 channel = 0;
3477 tSirMacAddr targetApBssid;
3478 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003479#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3480 tCsrHandoffRequest handoffInfo;
3481#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003482 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003483 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3484
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003485 /* if not associated, no need to proceed with reassoc */
3486 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3487 {
3488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3489 ret = -EINVAL;
3490 goto exit;
3491 }
3492
3493 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3494 if (eHAL_STATUS_SUCCESS != status)
3495 {
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "%s: Failed to parse reassoc command data", __func__);
3498 ret = -EINVAL;
3499 goto exit;
3500 }
3501
3502 /* if the target bssid is same as currently associated AP,
3503 then no need to proceed with reassoc */
3504 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3505 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3506 {
3507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3508 ret = -EINVAL;
3509 goto exit;
3510 }
3511
3512 /* Check channel number is a valid channel number */
3513 if(VOS_STATUS_SUCCESS !=
3514 wlan_hdd_validate_operation_channel(pAdapter, channel))
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003517 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003518 return -EINVAL;
3519 }
3520
3521 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003522#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3523 handoffInfo.channel = channel;
3524 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3525 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3526#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003527 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003528 else if (strncmp(command, "SETWESMODE", 10) == 0)
3529 {
3530 tANI_U8 *value = command;
3531 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3532
3533 /* Move pointer to ahead of SETWESMODE<delimiter> */
3534 value = value + 11;
3535 /* Convert the value from ascii to integer */
3536 ret = kstrtou8(value, 10, &wesMode);
3537 if (ret < 0)
3538 {
3539 /* If the input value is greater than max value of datatype, then also
3540 kstrtou8 fails */
3541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3542 "%s: kstrtou8 failed range [%d - %d]", __func__,
3543 CFG_ENABLE_WES_MODE_NAME_MIN,
3544 CFG_ENABLE_WES_MODE_NAME_MAX);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548
3549 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3550 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "WES Mode value %d is out of range"
3554 " (Min: %d Max: %d)", wesMode,
3555 CFG_ENABLE_WES_MODE_NAME_MIN,
3556 CFG_ENABLE_WES_MODE_NAME_MAX);
3557 ret = -EINVAL;
3558 goto exit;
3559 }
3560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3561 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3562
3563 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3564 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3565 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303566 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003567 {
3568 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3569 char extra[32];
3570 tANI_U8 len = 0;
3571
Arif Hussain826d9412013-11-12 16:44:54 -08003572 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05303573 len = VOS_MIN(priv_data.total_len, len + 1);
3574 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3576 "%s: failed to copy data to user buffer", __func__);
3577 ret = -EFAULT;
3578 goto exit;
3579 }
3580 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003581#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003582#ifdef FEATURE_WLAN_LFR
3583 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3584 {
3585 tANI_U8 *value = command;
3586 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3587
3588 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3589 value = value + 12;
3590 /* Convert the value from ascii to integer */
3591 ret = kstrtou8(value, 10, &lfrMode);
3592 if (ret < 0)
3593 {
3594 /* If the input value is greater than max value of datatype, then also
3595 kstrtou8 fails */
3596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3597 "%s: kstrtou8 failed range [%d - %d]", __func__,
3598 CFG_LFR_FEATURE_ENABLED_MIN,
3599 CFG_LFR_FEATURE_ENABLED_MAX);
3600 ret = -EINVAL;
3601 goto exit;
3602 }
3603
3604 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3605 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3606 {
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "lfr mode value %d is out of range"
3609 " (Min: %d Max: %d)", lfrMode,
3610 CFG_LFR_FEATURE_ENABLED_MIN,
3611 CFG_LFR_FEATURE_ENABLED_MAX);
3612 ret = -EINVAL;
3613 goto exit;
3614 }
3615
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3617 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3618
3619 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3620 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3621 }
3622#endif
3623#ifdef WLAN_FEATURE_VOWIFI_11R
3624 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3625 {
3626 tANI_U8 *value = command;
3627 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3628
3629 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3630 value = value + 18;
3631 /* Convert the value from ascii to integer */
3632 ret = kstrtou8(value, 10, &ft);
3633 if (ret < 0)
3634 {
3635 /* If the input value is greater than max value of datatype, then also
3636 kstrtou8 fails */
3637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3638 "%s: kstrtou8 failed range [%d - %d]", __func__,
3639 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3640 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3641 ret = -EINVAL;
3642 goto exit;
3643 }
3644
3645 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3646 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3647 {
3648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "ft mode value %d is out of range"
3650 " (Min: %d Max: %d)", ft,
3651 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3652 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3653 ret = -EINVAL;
3654 goto exit;
3655 }
3656
3657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3658 "%s: Received Command to change ft mode = %d", __func__, ft);
3659
3660 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3661 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3662 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303663 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3664 {
3665 tANI_U8 *value = command;
3666 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303667
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303668 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3669 value = value + 15;
3670 /* Convert the value from ascii to integer */
3671 ret = kstrtou8(value, 10, &dfsScanMode);
3672 if (ret < 0)
3673 {
3674 /* If the input value is greater than max value of
3675 datatype, then also kstrtou8 fails
3676 */
3677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3678 "%s: kstrtou8 failed range [%d - %d]", __func__,
3679 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3680 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3681 ret = -EINVAL;
3682 goto exit;
3683 }
3684
3685 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3686 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3687 {
3688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3689 "dfsScanMode value %d is out of range"
3690 " (Min: %d Max: %d)", dfsScanMode,
3691 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3692 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3693 ret = -EINVAL;
3694 goto exit;
3695 }
3696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3697 "%s: Received Command to Set DFS Scan Mode = %d",
3698 __func__, dfsScanMode);
3699
3700 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3701 }
3702 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3703 {
3704 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3705 char extra[32];
3706 tANI_U8 len = 0;
3707
3708 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05303709 len = VOS_MIN(priv_data.total_len, len + 1);
3710 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303711 {
3712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3713 "%s: failed to copy data to user buffer", __func__);
3714 ret = -EFAULT;
3715 goto exit;
3716 }
3717 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303718 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3719 {
3720 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303721 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303722 tSirMacAddr targetApBssid;
3723 tANI_U8 trigger = 0;
3724 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303725 tHalHandle hHal;
3726 v_U32_t roamId = 0;
3727 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303728 hdd_station_ctx_t *pHddStaCtx = NULL;
3729 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303730 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303731
3732 /* if not associated, no need to proceed with reassoc */
3733 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3734 {
3735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3736 ret = -EINVAL;
3737 goto exit;
3738 }
3739
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303740 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303741 if (eHAL_STATUS_SUCCESS != status)
3742 {
3743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3744 "%s: Failed to parse reassoc command data", __func__);
3745 ret = -EINVAL;
3746 goto exit;
3747 }
3748
3749 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303750 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303751 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3752 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3753 {
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3755 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3756 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303757 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3758 &modProfileFields);
3759 sme_RoamReassoc(hHal, pAdapter->sessionId,
3760 NULL, modProfileFields, &roamId, 1);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303761 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303762 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303763
3764 /* Check channel number is a valid channel number */
3765 if(VOS_STATUS_SUCCESS !=
3766 wlan_hdd_validate_operation_channel(pAdapter, channel))
3767 {
3768 hddLog(VOS_TRACE_LEVEL_ERROR,
3769 "%s: Invalid Channel [%d]", __func__, channel);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303770 return -EINVAL;
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303771 }
3772
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303773 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303774
3775 /* Proceed with scan/roam */
3776 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3777 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303778 (tSmeFastRoamTrigger)(trigger),
3779 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303780 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003781#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003782#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003783 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3784 {
3785 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003786 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003787
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003788 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003789 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003790 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003791 hdd_is_okc_mode_enabled(pHddCtx) &&
3792 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3793 {
3794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003795 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003796 " hence this operation is not permitted!", __func__);
3797 ret = -EPERM;
3798 goto exit;
3799 }
3800
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003801 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3802 value = value + 11;
3803 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003804 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003805 if (ret < 0)
3806 {
3807 /* If the input value is greater than max value of datatype, then also
3808 kstrtou8 fails */
3809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3810 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003811 CFG_ESE_FEATURE_ENABLED_MIN,
3812 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003813 ret = -EINVAL;
3814 goto exit;
3815 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003816 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3817 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003818 {
3819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003820 "Ese mode value %d is out of range"
3821 " (Min: %d Max: %d)", eseMode,
3822 CFG_ESE_FEATURE_ENABLED_MIN,
3823 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003824 ret = -EINVAL;
3825 goto exit;
3826 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003828 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003829
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003830 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3831 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003832 }
3833#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003834 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3835 {
3836 tANI_U8 *value = command;
3837 tANI_BOOLEAN roamScanControl = 0;
3838
3839 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3840 value = value + 19;
3841 /* Convert the value from ascii to integer */
3842 ret = kstrtou8(value, 10, &roamScanControl);
3843 if (ret < 0)
3844 {
3845 /* If the input value is greater than max value of datatype, then also
3846 kstrtou8 fails */
3847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3848 "%s: kstrtou8 failed ", __func__);
3849 ret = -EINVAL;
3850 goto exit;
3851 }
3852
3853 if (0 != roamScanControl)
3854 {
3855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3856 "roam scan control invalid value = %d",
3857 roamScanControl);
3858 ret = -EINVAL;
3859 goto exit;
3860 }
3861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3862 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3863
3864 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3865 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003866#ifdef FEATURE_WLAN_OKC
3867 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3868 {
3869 tANI_U8 *value = command;
3870 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3871
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003872 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003873 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003874 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003875 hdd_is_okc_mode_enabled(pHddCtx) &&
3876 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3877 {
3878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003879 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003880 " hence this operation is not permitted!", __func__);
3881 ret = -EPERM;
3882 goto exit;
3883 }
3884
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003885 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3886 value = value + 11;
3887 /* Convert the value from ascii to integer */
3888 ret = kstrtou8(value, 10, &okcMode);
3889 if (ret < 0)
3890 {
3891 /* If the input value is greater than max value of datatype, then also
3892 kstrtou8 fails */
3893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3894 "%s: kstrtou8 failed range [%d - %d]", __func__,
3895 CFG_OKC_FEATURE_ENABLED_MIN,
3896 CFG_OKC_FEATURE_ENABLED_MAX);
3897 ret = -EINVAL;
3898 goto exit;
3899 }
3900
3901 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3902 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3903 {
3904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3905 "Okc mode value %d is out of range"
3906 " (Min: %d Max: %d)", okcMode,
3907 CFG_OKC_FEATURE_ENABLED_MIN,
3908 CFG_OKC_FEATURE_ENABLED_MAX);
3909 ret = -EINVAL;
3910 goto exit;
3911 }
3912
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3914 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3915
3916 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3917 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003918#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303919 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003920 {
3921 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3922 char extra[32];
3923 tANI_U8 len = 0;
3924
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003925 len = scnprintf(extra, sizeof(extra), "%s %d",
3926 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05303927 len = VOS_MIN(priv_data.total_len, len + 1);
3928 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003929 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 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303935#ifdef WLAN_FEATURE_PACKET_FILTERING
3936 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3937 {
3938 tANI_U8 filterType = 0;
3939 tANI_U8 *value = command;
3940
3941 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3942 value = value + 22;
3943
3944 /* Convert the value from ascii to integer */
3945 ret = kstrtou8(value, 10, &filterType);
3946 if (ret < 0)
3947 {
3948 /* If the input value is greater than max value of datatype,
3949 * then also kstrtou8 fails
3950 */
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3952 "%s: kstrtou8 failed range ", __func__);
3953 ret = -EINVAL;
3954 goto exit;
3955 }
3956
3957 if (filterType != 0 && filterType != 1)
3958 {
3959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3960 "%s: Accepted Values are 0 and 1 ", __func__);
3961 ret = -EINVAL;
3962 goto exit;
3963 }
3964 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3965 pAdapter->sessionId);
3966 }
3967#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303968 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3969 {
Kiet Lamad161252014-07-22 11:23:32 -07003970 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303971 int ret;
3972
Kiet Lamad161252014-07-22 11:23:32 -07003973 dhcpPhase = command + 11;
3974 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303975 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003977 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303978
3979 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003980
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303981 ret = wlan_hdd_scan_abort(pAdapter);
3982 if (ret < 0)
3983 {
3984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3985 FL("failed to abort existing scan %d"), ret);
3986 }
3987
Kiet Lamad161252014-07-22 11:23:32 -07003988 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3989 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303990 }
Kiet Lamad161252014-07-22 11:23:32 -07003991 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303992 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003994 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303995
3996 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003997
3998 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3999 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304000 }
4001 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004002 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4003 {
c_hpothudbefd3e2014-04-28 15:59:47 +05304004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4005 FL("making default scan to ACTIVE"));
4006 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004007 }
4008 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4009 {
c_hpothudbefd3e2014-04-28 15:59:47 +05304010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4011 FL("making default scan to PASSIVE"));
4012 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004013 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304014 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4015 {
4016 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4017 char extra[32];
4018 tANI_U8 len = 0;
4019
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304020 memset(extra, 0, sizeof(extra));
4021 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304022 len = VOS_MIN(priv_data.total_len, len + 1);
4023 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4025 "%s: failed to copy data to user buffer", __func__);
4026 ret = -EFAULT;
4027 goto exit;
4028 }
4029 ret = len;
4030 }
4031 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4032 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304033 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304034 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004035 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4036 {
4037 tANI_U8 filterType = 0;
4038 tANI_U8 *value;
4039 value = command + 9;
4040
4041 /* Convert the value from ascii to integer */
4042 ret = kstrtou8(value, 10, &filterType);
4043 if (ret < 0)
4044 {
4045 /* If the input value is greater than max value of datatype,
4046 * then also kstrtou8 fails
4047 */
4048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4049 "%s: kstrtou8 failed range ", __func__);
4050 ret = -EINVAL;
4051 goto exit;
4052 }
4053 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4054 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4055 {
4056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4057 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4058 " 2-Sink ", __func__);
4059 ret = -EINVAL;
4060 goto exit;
4061 }
4062 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4063 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304064 pScanInfo = &pHddCtx->scan_info;
4065 if (filterType && pScanInfo != NULL &&
4066 pHddCtx->scan_info.mScanPending)
4067 {
4068 /*Miracast Session started. Abort Scan */
4069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4070 "%s, Aborting Scan For Miracast",__func__);
4071 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4072 eCSR_SCAN_ABORT_DEFAULT);
4073 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004074 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304075 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004076 }
Leo Chang614d2072013-08-22 14:59:44 -07004077 else if (strncmp(command, "SETMCRATE", 9) == 0)
4078 {
Leo Chang614d2072013-08-22 14:59:44 -07004079 tANI_U8 *value = command;
4080 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004081 tSirRateUpdateInd *rateUpdate;
4082 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004083
4084 /* Only valid for SAP mode */
4085 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4086 {
4087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4088 "%s: SAP mode is not running", __func__);
4089 ret = -EFAULT;
4090 goto exit;
4091 }
4092
4093 /* Move pointer to ahead of SETMCRATE<delimiter> */
4094 /* input value is in units of hundred kbps */
4095 value = value + 10;
4096 /* Convert the value from ascii to integer, decimal base */
4097 ret = kstrtouint(value, 10, &targetRate);
4098
Leo Chang1f98cbd2013-10-17 15:03:52 -07004099 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4100 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004101 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004102 hddLog(VOS_TRACE_LEVEL_ERROR,
4103 "%s: SETMCRATE indication alloc fail", __func__);
4104 ret = -EFAULT;
4105 goto exit;
4106 }
4107 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4108
4109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4110 "MC Target rate %d", targetRate);
4111 /* Ignore unicast */
4112 rateUpdate->ucastDataRate = -1;
4113 rateUpdate->mcastDataRate24GHz = targetRate;
4114 rateUpdate->mcastDataRate5GHz = targetRate;
4115 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4116 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4117 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4118 if (eHAL_STATUS_SUCCESS != status)
4119 {
4120 hddLog(VOS_TRACE_LEVEL_ERROR,
4121 "%s: SET_MC_RATE failed", __func__);
4122 vos_mem_free(rateUpdate);
4123 ret = -EFAULT;
4124 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004125 }
4126 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304127#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004128 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304129 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004130 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304131 }
4132#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004133#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004134 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4135 {
4136 tANI_U8 *value = command;
4137 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4138 tANI_U8 numChannels = 0;
4139 eHalStatus status = eHAL_STATUS_SUCCESS;
4140
4141 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4142 if (eHAL_STATUS_SUCCESS != status)
4143 {
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4145 "%s: Failed to parse channel list information", __func__);
4146 ret = -EINVAL;
4147 goto exit;
4148 }
4149
4150 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4151 {
4152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4153 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4154 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4155 ret = -EINVAL;
4156 goto exit;
4157 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004158 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004159 ChannelList,
4160 numChannels);
4161 if (eHAL_STATUS_SUCCESS != status)
4162 {
4163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4164 "%s: Failed to update channel list information", __func__);
4165 ret = -EINVAL;
4166 goto exit;
4167 }
4168 }
4169 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4170 {
4171 tANI_U8 *value = command;
4172 char extra[128] = {0};
4173 int len = 0;
4174 tANI_U8 tid = 0;
4175 hdd_station_ctx_t *pHddStaCtx = NULL;
4176 tAniTrafStrmMetrics tsmMetrics;
4177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4178
4179 /* if not associated, return error */
4180 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4181 {
4182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4183 ret = -EINVAL;
4184 goto exit;
4185 }
4186
4187 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4188 value = value + 12;
4189 /* Convert the value from ascii to integer */
4190 ret = kstrtou8(value, 10, &tid);
4191 if (ret < 0)
4192 {
4193 /* If the input value is greater than max value of datatype, then also
4194 kstrtou8 fails */
4195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4196 "%s: kstrtou8 failed range [%d - %d]", __func__,
4197 TID_MIN_VALUE,
4198 TID_MAX_VALUE);
4199 ret = -EINVAL;
4200 goto exit;
4201 }
4202
4203 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4204 {
4205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4206 "tid value %d is out of range"
4207 " (Min: %d Max: %d)", tid,
4208 TID_MIN_VALUE,
4209 TID_MAX_VALUE);
4210 ret = -EINVAL;
4211 goto exit;
4212 }
4213
4214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4215 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4216
4217 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4218 {
4219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4220 "%s: failed to get tsm stats", __func__);
4221 ret = -EFAULT;
4222 goto exit;
4223 }
4224
4225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4226 "UplinkPktQueueDly(%d)\n"
4227 "UplinkPktQueueDlyHist[0](%d)\n"
4228 "UplinkPktQueueDlyHist[1](%d)\n"
4229 "UplinkPktQueueDlyHist[2](%d)\n"
4230 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304231 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004232 "UplinkPktLoss(%d)\n"
4233 "UplinkPktCount(%d)\n"
4234 "RoamingCount(%d)\n"
4235 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4236 tsmMetrics.UplinkPktQueueDlyHist[0],
4237 tsmMetrics.UplinkPktQueueDlyHist[1],
4238 tsmMetrics.UplinkPktQueueDlyHist[2],
4239 tsmMetrics.UplinkPktQueueDlyHist[3],
4240 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4241 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4242
4243 /* Output TSM stats is of the format
4244 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4245 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004246 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004247 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4248 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4249 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4250 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4251 tsmMetrics.RoamingDly);
4252
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304253 len = VOS_MIN(priv_data.total_len, len + 1);
4254 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4256 "%s: failed to copy data to user buffer", __func__);
4257 ret = -EFAULT;
4258 goto exit;
4259 }
4260 }
4261 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4262 {
4263 tANI_U8 *value = command;
4264 tANI_U8 *cckmIe = NULL;
4265 tANI_U8 cckmIeLen = 0;
4266 eHalStatus status = eHAL_STATUS_SUCCESS;
4267
4268 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4269 if (eHAL_STATUS_SUCCESS != status)
4270 {
4271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4272 "%s: Failed to parse cckm ie data", __func__);
4273 ret = -EINVAL;
4274 goto exit;
4275 }
4276
4277 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4278 {
4279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4280 "%s: CCKM Ie input length is more than max[%d]", __func__,
4281 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004282 vos_mem_free(cckmIe);
4283 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004284 ret = -EINVAL;
4285 goto exit;
4286 }
4287 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004288 vos_mem_free(cckmIe);
4289 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004290 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004291 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4292 {
4293 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004294 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004295 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004296
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004297 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004298 if (eHAL_STATUS_SUCCESS != status)
4299 {
4300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004301 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004302 ret = -EINVAL;
4303 goto exit;
4304 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004305 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4307 hdd_indicateEseBcnReportNoResults (pAdapter,
4308 eseBcnReq.bcnReq[0].measurementToken,
4309 0x02, //BIT(1) set for measurement done
4310 0); // no BSS
4311 goto exit;
4312 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004313
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004314 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4315 if (eHAL_STATUS_SUCCESS != status)
4316 {
4317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4318 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4319 ret = -EINVAL;
4320 goto exit;
4321 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004322 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004323#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304324 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4325 {
4326 eHalStatus status;
4327 char buf[32], len;
4328 long waitRet;
4329 bcnMissRateContext_t getBcnMissRateCtx;
4330
4331 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4332
4333 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4334 {
4335 hddLog(VOS_TRACE_LEVEL_WARN,
4336 FL("GETBCNMISSRATE: STA is not in connected state"));
4337 ret = -1;
4338 goto exit;
4339 }
4340
4341 init_completion(&(getBcnMissRateCtx.completion));
4342 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4343
4344 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4345 pAdapter->sessionId,
4346 (void *)getBcnMissRateCB,
4347 (void *)(&getBcnMissRateCtx));
4348 if( eHAL_STATUS_SUCCESS != status)
4349 {
4350 hddLog(VOS_TRACE_LEVEL_INFO,
4351 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355
4356 waitRet = wait_for_completion_interruptible_timeout
4357 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4358 if(waitRet <= 0)
4359 {
4360 hddLog(VOS_TRACE_LEVEL_ERROR,
4361 FL("failed to wait on bcnMissRateComp %d"), ret);
4362
4363 //Make magic number to zero so that callback is not called.
4364 spin_lock(&hdd_context_lock);
4365 getBcnMissRateCtx.magic = 0x0;
4366 spin_unlock(&hdd_context_lock);
4367 ret = -EINVAL;
4368 goto exit;
4369 }
4370
4371 hddLog(VOS_TRACE_LEVEL_INFO,
4372 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4373
4374 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4375 if (copy_to_user(priv_data.buf, &buf, len + 1))
4376 {
4377 hddLog(VOS_TRACE_LEVEL_ERROR,
4378 "%s: failed to copy data to user buffer", __func__);
4379 ret = -EFAULT;
4380 goto exit;
4381 }
4382 ret = len;
4383 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304384#ifdef FEATURE_WLAN_TDLS
4385 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4386 tANI_U8 *value = command;
4387 int set_value;
4388 /* Move pointer to ahead of TDLSOFFCH*/
4389 value += 26;
4390 sscanf(value, "%d", &set_value);
4391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4392 "%s: Tdls offchannel offset:%d",
4393 __func__, set_value);
4394 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4395 if (ret < 0)
4396 {
4397 ret = -EINVAL;
4398 goto exit;
4399 }
4400
4401 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4402 tANI_U8 *value = command;
4403 int set_value;
4404 /* Move pointer to ahead of tdlsoffchnmode*/
4405 value += 18;
c_manjee82323892015-12-08 12:40:34 +05304406 ret = sscanf(value, "%d", &set_value);
4407 if (ret != 1) {
4408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4409 FL("No input identified"));
4410 ret = -EINVAL;
4411 goto exit;
4412 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4414 "%s: Tdls offchannel mode:%d",
4415 __func__, set_value);
4416 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4417 if (ret < 0)
4418 {
4419 ret = -EINVAL;
4420 goto exit;
4421 }
4422 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4423 tANI_U8 *value = command;
4424 int set_value;
4425 /* Move pointer to ahead of TDLSOFFCH*/
4426 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05304427 ret = sscanf(value, "%d", &set_value);
4428 if (ret != 1) {
4429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4430 "Wrong value is given for hdd_set_tdls_offchannel");
4431 ret = -EINVAL;
4432 goto exit;
4433 }
4434
Atul Mittal87ec2422014-09-24 13:12:50 +05304435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4436 "%s: Tdls offchannel num: %d",
4437 __func__, set_value);
4438 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4439 if (ret < 0)
4440 {
4441 ret = -EINVAL;
4442 goto exit;
4443 }
4444 }
4445#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304446 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4447 {
4448 eHalStatus status;
4449 char *buf = NULL;
4450 char len;
4451 long waitRet;
4452 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304453 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304454 tANI_U8 *ptr = command;
4455 int stats = *(ptr + 11) - '0';
4456
4457 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4458 if (!IS_FEATURE_FW_STATS_ENABLE)
4459 {
4460 hddLog(VOS_TRACE_LEVEL_INFO,
4461 FL("Get Firmware stats feature not supported"));
4462 ret = -EINVAL;
4463 goto exit;
4464 }
4465
4466 if (FW_STATS_MAX <= stats || 0 >= stats)
4467 {
4468 hddLog(VOS_TRACE_LEVEL_INFO,
4469 FL(" stats %d not supported"),stats);
4470 ret = -EINVAL;
4471 goto exit;
4472 }
4473
4474 init_completion(&(fwStatsCtx.completion));
4475 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4476 fwStatsCtx.pAdapter = pAdapter;
4477 fwStatsRsp->type = 0;
4478 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304479 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304480 if (eHAL_STATUS_SUCCESS != status)
4481 {
4482 hddLog(VOS_TRACE_LEVEL_ERROR,
4483 FL(" fail to post WDA cmd status = %d"), status);
4484 ret = -EINVAL;
4485 goto exit;
4486 }
4487 waitRet = wait_for_completion_timeout
4488 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4489 if (waitRet <= 0)
4490 {
4491 hddLog(VOS_TRACE_LEVEL_ERROR,
4492 FL("failed to wait on GwtFwstats"));
4493 //Make magic number to zero so that callback is not executed.
4494 spin_lock(&hdd_context_lock);
4495 fwStatsCtx.magic = 0x0;
4496 spin_unlock(&hdd_context_lock);
4497 ret = -EINVAL;
4498 goto exit;
4499 }
4500 if (fwStatsRsp->type)
4501 {
4502 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4503 if (!buf)
4504 {
4505 hddLog(VOS_TRACE_LEVEL_ERROR,
4506 FL(" failed to allocate memory"));
4507 ret = -ENOMEM;
4508 goto exit;
4509 }
4510 switch( fwStatsRsp->type )
4511 {
4512 case FW_UBSP_STATS:
4513 {
4514 len = snprintf(buf, FW_STATE_RSP_LEN,
4515 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304516 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4517 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304518 }
4519 break;
4520 default:
4521 {
4522 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4523 ret = -EFAULT;
4524 kfree(buf);
4525 goto exit;
4526 }
4527 }
4528 if (copy_to_user(priv_data.buf, buf, len + 1))
4529 {
4530 hddLog(VOS_TRACE_LEVEL_ERROR,
4531 FL(" failed to copy data to user buffer"));
4532 ret = -EFAULT;
4533 kfree(buf);
4534 goto exit;
4535 }
4536 ret = len;
4537 kfree(buf);
4538 }
4539 else
4540 {
4541 hddLog(VOS_TRACE_LEVEL_ERROR,
4542 FL("failed to fetch the stats"));
4543 ret = -EFAULT;
4544 goto exit;
4545 }
4546
4547 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304548 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4549 {
4550 /*
4551 * this command wld be called by user-space when it detects WLAN
4552 * ON after airplane mode is set. When APM is set, WLAN turns off.
4553 * But it can be turned back on. Otherwise; when APM is turned back
4554 * off, WLAN wld turn back on. So at that point the command is
4555 * expected to come down. 0 means disable, 1 means enable. The
4556 * constraint is removed when parameter 1 is set or different
4557 * country code is set
4558 */
4559 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4560 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05304561 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4562 {
4563 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4564 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004565 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304566 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4567 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4568 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304569 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4570 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 }
4573exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304574 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 if (command)
4576 {
4577 kfree(command);
4578 }
4579 return ret;
4580}
4581
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004582#ifdef CONFIG_COMPAT
4583static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4584{
4585 struct {
4586 compat_uptr_t buf;
4587 int used_len;
4588 int total_len;
4589 } compat_priv_data;
4590 hdd_priv_data_t priv_data;
4591 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004592
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004593 /*
4594 * Note that pAdapter and ifr have already been verified by caller,
4595 * and HDD context has also been validated
4596 */
4597 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4598 sizeof(compat_priv_data))) {
4599 ret = -EFAULT;
4600 goto exit;
4601 }
4602 priv_data.buf = compat_ptr(compat_priv_data.buf);
4603 priv_data.used_len = compat_priv_data.used_len;
4604 priv_data.total_len = compat_priv_data.total_len;
4605 ret = hdd_driver_command(pAdapter, &priv_data);
4606 exit:
4607 return ret;
4608}
4609#else /* CONFIG_COMPAT */
4610static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4611{
4612 /* will never be invoked */
4613 return 0;
4614}
4615#endif /* CONFIG_COMPAT */
4616
4617static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4618{
4619 hdd_priv_data_t priv_data;
4620 int ret = 0;
4621
4622 /*
4623 * Note that pAdapter and ifr have already been verified by caller,
4624 * and HDD context has also been validated
4625 */
4626 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4627 ret = -EFAULT;
4628 } else {
4629 ret = hdd_driver_command(pAdapter, &priv_data);
4630 }
4631 return ret;
4632}
4633
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304634int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004635{
4636 hdd_adapter_t *pAdapter;
4637 hdd_context_t *pHddCtx;
4638 int ret;
4639
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304640 ENTER();
4641
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004642 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4643 if (NULL == pAdapter) {
4644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4645 "%s: HDD adapter context is Null", __func__);
4646 ret = -ENODEV;
4647 goto exit;
4648 }
4649 if (dev != pAdapter->dev) {
4650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4651 "%s: HDD adapter/dev inconsistency", __func__);
4652 ret = -ENODEV;
4653 goto exit;
4654 }
4655
4656 if ((!ifr) || (!ifr->ifr_data)) {
4657 ret = -EINVAL;
4658 goto exit;
4659 }
4660
4661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4662 ret = wlan_hdd_validate_context(pHddCtx);
4663 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004664 ret = -EBUSY;
4665 goto exit;
4666 }
4667
4668 switch (cmd) {
4669 case (SIOCDEVPRIVATE + 1):
4670 if (is_compat_task())
4671 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4672 else
4673 ret = hdd_driver_ioctl(pAdapter, ifr);
4674 break;
4675 default:
4676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4677 __func__, cmd);
4678 ret = -EINVAL;
4679 break;
4680 }
4681 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304682 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004683 return ret;
4684}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004685
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304686int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4687{
4688 int ret;
4689
4690 vos_ssr_protect(__func__);
4691 ret = __hdd_ioctl(dev, ifr, cmd);
4692 vos_ssr_unprotect(__func__);
4693
4694 return ret;
4695}
4696
Katya Nigame7b69a82015-04-28 15:24:06 +05304697int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4698{
4699 return 0;
4700}
4701
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004702#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004703/**---------------------------------------------------------------------------
4704
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004705 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004706
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004707 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004708 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4709 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4710 <space>Scan Mode N<space>Meas Duration N
4711 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4712 then take N.
4713 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4714 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4715 This function does not take care of removing duplicate channels from the list
4716
4717 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004718 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004719
4720 \return - 0 for success non-zero for failure
4721
4722 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004723static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4724 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004725{
4726 tANI_U8 *inPtr = pValue;
4727 int tempInt = 0;
4728 int j = 0, i = 0, v = 0;
4729 char buf[32];
4730
4731 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4732 /*no argument after the command*/
4733 if (NULL == inPtr)
4734 {
4735 return -EINVAL;
4736 }
4737 /*no space after the command*/
4738 else if (SPACE_ASCII_VALUE != *inPtr)
4739 {
4740 return -EINVAL;
4741 }
4742
4743 /*removing empty spaces*/
4744 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4745
4746 /*no argument followed by spaces*/
4747 if ('\0' == *inPtr) return -EINVAL;
4748
4749 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004750 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004751 if (1 != v) return -EINVAL;
4752
4753 v = kstrtos32(buf, 10, &tempInt);
4754 if ( v < 0) return -EINVAL;
4755
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004756 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004757
4758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004759 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004760
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004761 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004762 {
4763 for (i = 0; i < 4; i++)
4764 {
4765 /*inPtr pointing to the beginning of first space after number of ie fields*/
4766 inPtr = strpbrk( inPtr, " " );
4767 /*no ie data after the number of ie fields argument*/
4768 if (NULL == inPtr) return -EINVAL;
4769
4770 /*removing empty space*/
4771 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4772
4773 /*no ie data after the number of ie fields argument and spaces*/
4774 if ( '\0' == *inPtr ) return -EINVAL;
4775
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004776 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004777 if (1 != v) return -EINVAL;
4778
4779 v = kstrtos32(buf, 10, &tempInt);
4780 if (v < 0) return -EINVAL;
4781
4782 switch (i)
4783 {
4784 case 0: /* Measurement token */
4785 if (tempInt <= 0)
4786 {
4787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4788 "Invalid Measurement Token(%d)", tempInt);
4789 return -EINVAL;
4790 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004791 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004792 break;
4793
4794 case 1: /* Channel number */
4795 if ((tempInt <= 0) ||
4796 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4797 {
4798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4799 "Invalid Channel Number(%d)", tempInt);
4800 return -EINVAL;
4801 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004802 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004803 break;
4804
4805 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004806 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004807 {
4808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4809 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4810 return -EINVAL;
4811 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004812 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004813 break;
4814
4815 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004816 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4817 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004818 {
4819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4820 "Invalid Measurement Duration(%d)", tempInt);
4821 return -EINVAL;
4822 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004823 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004824 break;
4825 }
4826 }
4827 }
4828
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004829 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004830 {
4831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304832 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004833 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004834 pEseBcnReq->bcnReq[j].measurementToken,
4835 pEseBcnReq->bcnReq[j].channel,
4836 pEseBcnReq->bcnReq[j].scanMode,
4837 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004838 }
4839
4840 return VOS_STATUS_SUCCESS;
4841}
4842
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004843static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4844{
4845 struct statsContext *pStatsContext = NULL;
4846 hdd_adapter_t *pAdapter = NULL;
4847
4848 if (NULL == pContext)
4849 {
4850 hddLog(VOS_TRACE_LEVEL_ERROR,
4851 "%s: Bad param, pContext [%p]",
4852 __func__, pContext);
4853 return;
4854 }
4855
Jeff Johnson72a40512013-12-19 10:14:15 -08004856 /* there is a race condition that exists between this callback
4857 function and the caller since the caller could time out either
4858 before or while this code is executing. we use a spinlock to
4859 serialize these actions */
4860 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004861
4862 pStatsContext = pContext;
4863 pAdapter = pStatsContext->pAdapter;
4864 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4865 {
4866 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004867 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004868 hddLog(VOS_TRACE_LEVEL_WARN,
4869 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4870 __func__, pAdapter, pStatsContext->magic);
4871 return;
4872 }
4873
Jeff Johnson72a40512013-12-19 10:14:15 -08004874 /* context is valid so caller is still waiting */
4875
4876 /* paranoia: invalidate the magic */
4877 pStatsContext->magic = 0;
4878
4879 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004880 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4881 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4882 tsmMetrics.UplinkPktQueueDlyHist,
4883 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4884 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4885 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4886 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4887 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4888 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4889 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4890
Jeff Johnson72a40512013-12-19 10:14:15 -08004891 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004892 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004893
4894 /* serialization is complete */
4895 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004896}
4897
4898
4899
4900static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4901 tAniTrafStrmMetrics* pTsmMetrics)
4902{
4903 hdd_station_ctx_t *pHddStaCtx = NULL;
4904 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004905 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004906 long lrc;
4907 struct statsContext context;
4908 hdd_context_t *pHddCtx = NULL;
4909
4910 if (NULL == pAdapter)
4911 {
4912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4913 return VOS_STATUS_E_FAULT;
4914 }
4915
4916 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4917 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4918
4919 /* we are connected prepare our callback context */
4920 init_completion(&context.completion);
4921 context.pAdapter = pAdapter;
4922 context.magic = STATS_CONTEXT_MAGIC;
4923
4924 /* query tsm stats */
4925 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4926 pHddStaCtx->conn_info.staId[ 0 ],
4927 pHddStaCtx->conn_info.bssId,
4928 &context, pHddCtx->pvosContext, tid);
4929
4930 if (eHAL_STATUS_SUCCESS != hstatus)
4931 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4933 __func__);
4934 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004935 }
4936 else
4937 {
4938 /* request was sent -- wait for the response */
4939 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4940 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004941 if (lrc <= 0)
4942 {
4943 hddLog(VOS_TRACE_LEVEL_ERROR,
4944 "%s: SME %s while retrieving statistics",
4945 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004946 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004947 }
4948 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004949
Jeff Johnson72a40512013-12-19 10:14:15 -08004950 /* either we never sent a request, we sent a request and received a
4951 response or we sent a request and timed out. if we never sent a
4952 request or if we sent a request and got a response, we want to
4953 clear the magic out of paranoia. if we timed out there is a
4954 race condition such that the callback function could be
4955 executing at the same time we are. of primary concern is if the
4956 callback function had already verified the "magic" but had not
4957 yet set the completion variable when a timeout occurred. we
4958 serialize these activities by invalidating the magic while
4959 holding a shared spinlock which will cause us to block if the
4960 callback is currently executing */
4961 spin_lock(&hdd_context_lock);
4962 context.magic = 0;
4963 spin_unlock(&hdd_context_lock);
4964
4965 if (VOS_STATUS_SUCCESS == vstatus)
4966 {
4967 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4968 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4969 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4970 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4971 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4972 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4973 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4974 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4975 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4976 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4977 }
4978 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004979}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004980#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004981
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004982#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004983void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4984{
4985 eCsrBand band = -1;
4986 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4987 switch (band)
4988 {
4989 case eCSR_BAND_ALL:
4990 *pBand = WLAN_HDD_UI_BAND_AUTO;
4991 break;
4992
4993 case eCSR_BAND_24:
4994 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4995 break;
4996
4997 case eCSR_BAND_5G:
4998 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4999 break;
5000
5001 default:
5002 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
5003 *pBand = -1;
5004 break;
5005 }
5006}
5007
5008/**---------------------------------------------------------------------------
5009
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005010 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
5011
5012 This function parses the send action frame data passed in the format
5013 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
5014
Srinivas Girigowda56076852013-08-20 14:00:50 -07005015 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005016 \param - pTargetApBssid Pointer to target Ap bssid
5017 \param - pChannel Pointer to the Target AP channel
5018 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
5019 \param - pBuf Pointer to data
5020 \param - pBufLen Pointer to data length
5021
5022 \return - 0 for success non-zero for failure
5023
5024 --------------------------------------------------------------------------*/
5025VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
5026 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
5027{
5028 tANI_U8 *inPtr = pValue;
5029 tANI_U8 *dataEnd;
5030 int tempInt;
5031 int j = 0;
5032 int i = 0;
5033 int v = 0;
5034 tANI_U8 tempBuf[32];
5035 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005036 /* 12 hexa decimal digits, 5 ':' and '\0' */
5037 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005038
5039 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5040 /*no argument after the command*/
5041 if (NULL == inPtr)
5042 {
5043 return -EINVAL;
5044 }
5045
5046 /*no space after the command*/
5047 else if (SPACE_ASCII_VALUE != *inPtr)
5048 {
5049 return -EINVAL;
5050 }
5051
5052 /*removing empty spaces*/
5053 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5054
5055 /*no argument followed by spaces*/
5056 if ('\0' == *inPtr)
5057 {
5058 return -EINVAL;
5059 }
5060
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005061 v = sscanf(inPtr, "%17s", macAddress);
5062 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005063 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5065 "Invalid MAC address or All hex inputs are not read (%d)", v);
5066 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005067 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005068
5069 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5070 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5071 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5072 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5073 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5074 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005075
5076 /* point to the next argument */
5077 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5078 /*no argument after the command*/
5079 if (NULL == inPtr) return -EINVAL;
5080
5081 /*removing empty spaces*/
5082 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5083
5084 /*no argument followed by spaces*/
5085 if ('\0' == *inPtr)
5086 {
5087 return -EINVAL;
5088 }
5089
5090 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005091 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005092 if (1 != v) return -EINVAL;
5093
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005094 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305095 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305096 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005097
5098 *pChannel = tempInt;
5099
5100 /* point to the next argument */
5101 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5102 /*no argument after the command*/
5103 if (NULL == inPtr) return -EINVAL;
5104 /*removing empty spaces*/
5105 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5106
5107 /*no argument followed by spaces*/
5108 if ('\0' == *inPtr)
5109 {
5110 return -EINVAL;
5111 }
5112
5113 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005114 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005115 if (1 != v) return -EINVAL;
5116
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005117 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005118 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005119
5120 *pDwellTime = tempInt;
5121
5122 /* point to the next argument */
5123 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5124 /*no argument after the command*/
5125 if (NULL == inPtr) return -EINVAL;
5126 /*removing empty spaces*/
5127 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5128
5129 /*no argument followed by spaces*/
5130 if ('\0' == *inPtr)
5131 {
5132 return -EINVAL;
5133 }
5134
5135 /* find the length of data */
5136 dataEnd = inPtr;
5137 while(('\0' != *dataEnd) )
5138 {
5139 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005140 }
Kiet Lambe150c22013-11-21 16:30:32 +05305141 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005142 if ( *pBufLen <= 0) return -EINVAL;
5143
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005144 /* Allocate the number of bytes based on the number of input characters
5145 whether it is even or odd.
5146 if the number of input characters are even, then we need N/2 byte.
5147 if the number of input characters are odd, then we need do (N+1)/2 to
5148 compensate rounding off.
5149 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5150 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5151 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005152 if (NULL == *pBuf)
5153 {
5154 hddLog(VOS_TRACE_LEVEL_FATAL,
5155 "%s: vos_mem_alloc failed ", __func__);
5156 return -EINVAL;
5157 }
5158
5159 /* the buffer received from the upper layer is character buffer,
5160 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5161 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5162 and f0 in 3rd location */
5163 for (i = 0, j = 0; j < *pBufLen; j += 2)
5164 {
Kiet Lambe150c22013-11-21 16:30:32 +05305165 if( j+1 == *pBufLen)
5166 {
5167 tempByte = hdd_parse_hex(inPtr[j]);
5168 }
5169 else
5170 {
5171 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5172 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005173 (*pBuf)[i++] = tempByte;
5174 }
5175 *pBufLen = i;
5176 return VOS_STATUS_SUCCESS;
5177}
5178
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005179/**---------------------------------------------------------------------------
5180
Srinivas Girigowdade697412013-02-14 16:31:48 -08005181 \brief hdd_parse_channellist() - HDD Parse channel list
5182
5183 This function parses the channel list passed in the format
5184 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005185 if the Number of channels (N) does not match with the actual number of channels passed
5186 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5187 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5188 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5189 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005190
5191 \param - pValue Pointer to input channel list
5192 \param - ChannelList Pointer to local output array to record channel list
5193 \param - pNumChannels Pointer to number of roam scan channels
5194
5195 \return - 0 for success non-zero for failure
5196
5197 --------------------------------------------------------------------------*/
5198VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5199{
5200 tANI_U8 *inPtr = pValue;
5201 int tempInt;
5202 int j = 0;
5203 int v = 0;
5204 char buf[32];
5205
5206 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5207 /*no argument after the command*/
5208 if (NULL == inPtr)
5209 {
5210 return -EINVAL;
5211 }
5212
5213 /*no space after the command*/
5214 else if (SPACE_ASCII_VALUE != *inPtr)
5215 {
5216 return -EINVAL;
5217 }
5218
5219 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005220 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005221
5222 /*no argument followed by spaces*/
5223 if ('\0' == *inPtr)
5224 {
5225 return -EINVAL;
5226 }
5227
5228 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005229 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005230 if (1 != v) return -EINVAL;
5231
Srinivas Girigowdade697412013-02-14 16:31:48 -08005232 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005233 if ((v < 0) ||
5234 (tempInt <= 0) ||
5235 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5236 {
5237 return -EINVAL;
5238 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005239
5240 *pNumChannels = tempInt;
5241
5242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5243 "Number of channels are: %d", *pNumChannels);
5244
5245 for (j = 0; j < (*pNumChannels); j++)
5246 {
5247 /*inPtr pointing to the beginning of first space after number of channels*/
5248 inPtr = strpbrk( inPtr, " " );
5249 /*no channel list after the number of channels argument*/
5250 if (NULL == inPtr)
5251 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005252 if (0 != j)
5253 {
5254 *pNumChannels = j;
5255 return VOS_STATUS_SUCCESS;
5256 }
5257 else
5258 {
5259 return -EINVAL;
5260 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005261 }
5262
5263 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005264 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005265
5266 /*no channel list after the number of channels argument and spaces*/
5267 if ( '\0' == *inPtr )
5268 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005269 if (0 != j)
5270 {
5271 *pNumChannels = j;
5272 return VOS_STATUS_SUCCESS;
5273 }
5274 else
5275 {
5276 return -EINVAL;
5277 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005278 }
5279
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005280 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005281 if (1 != v) return -EINVAL;
5282
Srinivas Girigowdade697412013-02-14 16:31:48 -08005283 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005284 if ((v < 0) ||
5285 (tempInt <= 0) ||
5286 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5287 {
5288 return -EINVAL;
5289 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005290 pChannelList[j] = tempInt;
5291
5292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5293 "Channel %d added to preferred channel list",
5294 pChannelList[j] );
5295 }
5296
Srinivas Girigowdade697412013-02-14 16:31:48 -08005297 return VOS_STATUS_SUCCESS;
5298}
5299
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005300
5301/**---------------------------------------------------------------------------
5302
5303 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5304
5305 This function parses the reasoc command data passed in the format
5306 REASSOC<space><bssid><space><channel>
5307
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005308 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005309 \param - pTargetApBssid Pointer to target Ap bssid
5310 \param - pChannel Pointer to the Target AP channel
5311
5312 \return - 0 for success non-zero for failure
5313
5314 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005315VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5316 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005317{
5318 tANI_U8 *inPtr = pValue;
5319 int tempInt;
5320 int v = 0;
5321 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005322 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005323 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005324
5325 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5326 /*no argument after the command*/
5327 if (NULL == inPtr)
5328 {
5329 return -EINVAL;
5330 }
5331
5332 /*no space after the command*/
5333 else if (SPACE_ASCII_VALUE != *inPtr)
5334 {
5335 return -EINVAL;
5336 }
5337
5338 /*removing empty spaces*/
5339 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5340
5341 /*no argument followed by spaces*/
5342 if ('\0' == *inPtr)
5343 {
5344 return -EINVAL;
5345 }
5346
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005347 v = sscanf(inPtr, "%17s", macAddress);
5348 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005349 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5351 "Invalid MAC address or All hex inputs are not read (%d)", v);
5352 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005353 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005354
5355 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5356 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5357 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5358 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5359 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5360 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005361
5362 /* point to the next argument */
5363 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5364 /*no argument after the command*/
5365 if (NULL == inPtr) return -EINVAL;
5366
5367 /*removing empty spaces*/
5368 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5369
5370 /*no argument followed by spaces*/
5371 if ('\0' == *inPtr)
5372 {
5373 return -EINVAL;
5374 }
5375
5376 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005377 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005378 if (1 != v) return -EINVAL;
5379
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005380 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005381 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305382 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005383 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5384 {
5385 return -EINVAL;
5386 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005387
5388 *pChannel = tempInt;
5389 return VOS_STATUS_SUCCESS;
5390}
5391
5392#endif
5393
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005394#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005395/**---------------------------------------------------------------------------
5396
5397 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5398
5399 This function parses the SETCCKM IE command
5400 SETCCKMIE<space><ie data>
5401
5402 \param - pValue Pointer to input data
5403 \param - pCckmIe Pointer to output cckm Ie
5404 \param - pCckmIeLen Pointer to output cckm ie length
5405
5406 \return - 0 for success non-zero for failure
5407
5408 --------------------------------------------------------------------------*/
5409VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5410 tANI_U8 *pCckmIeLen)
5411{
5412 tANI_U8 *inPtr = pValue;
5413 tANI_U8 *dataEnd;
5414 int j = 0;
5415 int i = 0;
5416 tANI_U8 tempByte = 0;
5417
5418 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5419 /*no argument after the command*/
5420 if (NULL == inPtr)
5421 {
5422 return -EINVAL;
5423 }
5424
5425 /*no space after the command*/
5426 else if (SPACE_ASCII_VALUE != *inPtr)
5427 {
5428 return -EINVAL;
5429 }
5430
5431 /*removing empty spaces*/
5432 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5433
5434 /*no argument followed by spaces*/
5435 if ('\0' == *inPtr)
5436 {
5437 return -EINVAL;
5438 }
5439
5440 /* find the length of data */
5441 dataEnd = inPtr;
5442 while(('\0' != *dataEnd) )
5443 {
5444 dataEnd++;
5445 ++(*pCckmIeLen);
5446 }
5447 if ( *pCckmIeLen <= 0) return -EINVAL;
5448
5449 /* Allocate the number of bytes based on the number of input characters
5450 whether it is even or odd.
5451 if the number of input characters are even, then we need N/2 byte.
5452 if the number of input characters are odd, then we need do (N+1)/2 to
5453 compensate rounding off.
5454 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5455 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5456 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5457 if (NULL == *pCckmIe)
5458 {
5459 hddLog(VOS_TRACE_LEVEL_FATAL,
5460 "%s: vos_mem_alloc failed ", __func__);
5461 return -EINVAL;
5462 }
5463 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5464 /* the buffer received from the upper layer is character buffer,
5465 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5466 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5467 and f0 in 3rd location */
5468 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5469 {
5470 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5471 (*pCckmIe)[i++] = tempByte;
5472 }
5473 *pCckmIeLen = i;
5474
5475 return VOS_STATUS_SUCCESS;
5476}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005477#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005478
Jeff Johnson295189b2012-06-20 16:38:30 -07005479/**---------------------------------------------------------------------------
5480
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005481 \brief hdd_is_valid_mac_address() - Validate MAC address
5482
5483 This function validates whether the given MAC address is valid or not
5484 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5485 where X is the hexa decimal digit character and separated by ':'
5486 This algorithm works even if MAC address is not separated by ':'
5487
5488 This code checks given input string mac contains exactly 12 hexadecimal digits.
5489 and a separator colon : appears in the input string only after
5490 an even number of hex digits.
5491
5492 \param - pMacAddr pointer to the input MAC address
5493 \return - 1 for valid and 0 for invalid
5494
5495 --------------------------------------------------------------------------*/
5496
5497v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5498{
5499 int xdigit = 0;
5500 int separator = 0;
5501 while (*pMacAddr)
5502 {
5503 if (isxdigit(*pMacAddr))
5504 {
5505 xdigit++;
5506 }
5507 else if (':' == *pMacAddr)
5508 {
5509 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5510 break;
5511
5512 ++separator;
5513 }
5514 else
5515 {
5516 separator = -1;
5517 /* Invalid MAC found */
5518 return 0;
5519 }
5520 ++pMacAddr;
5521 }
5522 return (xdigit == 12 && (separator == 5 || separator == 0));
5523}
5524
5525/**---------------------------------------------------------------------------
5526
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305527 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005528
5529 \param - dev Pointer to net_device structure
5530
5531 \return - 0 for success non-zero for failure
5532
5533 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305534int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005535{
5536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5537 hdd_context_t *pHddCtx;
5538 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5539 VOS_STATUS status;
5540 v_BOOL_t in_standby = TRUE;
5541
5542 if (NULL == pAdapter)
5543 {
5544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305545 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 return -ENODEV;
5547 }
5548
5549 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305550 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5551 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 if (NULL == pHddCtx)
5553 {
5554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005555 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 return -ENODEV;
5557 }
5558
5559 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5560 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5561 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005562 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5563 {
5564 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305565 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005566 in_standby = FALSE;
5567 break;
5568 }
5569 else
5570 {
5571 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5572 pAdapterNode = pNext;
5573 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 }
5575
5576 if (TRUE == in_standby)
5577 {
5578 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5579 {
5580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5581 "wlan out of power save", __func__);
5582 return -EINVAL;
5583 }
5584 }
5585
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005586 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5588 {
5589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005590 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305592 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 netif_tx_start_all_queues(dev);
5594 }
5595
5596 return 0;
5597}
5598
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305599/**---------------------------------------------------------------------------
5600
5601 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5602
5603 This is called in response to ifconfig up
5604
5605 \param - dev Pointer to net_device structure
5606
5607 \return - 0 for success non-zero for failure
5608
5609 --------------------------------------------------------------------------*/
5610int hdd_open(struct net_device *dev)
5611{
5612 int ret;
5613
5614 vos_ssr_protect(__func__);
5615 ret = __hdd_open(dev);
5616 vos_ssr_unprotect(__func__);
5617
5618 return ret;
5619}
5620
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305621int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005622{
5623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5624
5625 if(pAdapter == NULL) {
5626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005627 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005628 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 }
5630
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 return 0;
5632}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305633
5634int hdd_mon_open (struct net_device *dev)
5635{
5636 int ret;
5637
5638 vos_ssr_protect(__func__);
5639 ret = __hdd_mon_open(dev);
5640 vos_ssr_unprotect(__func__);
5641
5642 return ret;
5643}
5644
Katya Nigame7b69a82015-04-28 15:24:06 +05305645int hdd_mon_stop(struct net_device *dev)
5646{
5647 return 0;
5648}
5649
Jeff Johnson295189b2012-06-20 16:38:30 -07005650/**---------------------------------------------------------------------------
5651
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305652 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005653
5654 \param - dev Pointer to net_device structure
5655
5656 \return - 0 for success non-zero for failure
5657
5658 --------------------------------------------------------------------------*/
5659
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305660int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005661{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305662 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005663 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5664 hdd_context_t *pHddCtx;
5665 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5666 VOS_STATUS status;
5667 v_BOOL_t enter_standby = TRUE;
5668
5669 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 if (NULL == pAdapter)
5671 {
5672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305673 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 return -ENODEV;
5675 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305676 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305677 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305678
5679 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5680 ret = wlan_hdd_validate_context(pHddCtx);
5681 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305683 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 }
5685
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305686 /* Nothing to be done if the interface is not opened */
5687 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5688 {
5689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5690 "%s: NETDEV Interface is not OPENED", __func__);
5691 return -ENODEV;
5692 }
5693
5694 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005695 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305697
5698 /* Disable TX on the interface, after this hard_start_xmit() will not
5699 * be called on that interface
5700 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305703
5704 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 netif_carrier_off(pAdapter->dev);
5706
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305707 /* The interface is marked as down for outside world (aka kernel)
5708 * But the driver is pretty much alive inside. The driver needs to
5709 * tear down the existing connection on the netdev (session)
5710 * cleanup the data pipes and wait until the control plane is stabilized
5711 * for this interface. The call also needs to wait until the above
5712 * mentioned actions are completed before returning to the caller.
5713 * Notice that the hdd_stop_adapter is requested not to close the session
5714 * That is intentional to be able to scan if it is a STA/P2P interface
5715 */
5716 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305717#ifdef FEATURE_WLAN_TDLS
5718 mutex_lock(&pHddCtx->tdls_lock);
5719#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305720 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305721 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305722#ifdef FEATURE_WLAN_TDLS
5723 mutex_unlock(&pHddCtx->tdls_lock);
5724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 /* SoftAP ifaces should never go in power save mode
5726 making sure same here. */
5727 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5728 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 )
5731 {
5732 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5734 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 EXIT();
5736 return 0;
5737 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305738 /* Find if any iface is up. If any iface is up then can't put device to
5739 * sleep/power save mode
5740 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005741 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5742 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5743 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005744 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5745 {
5746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305747 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005748 enter_standby = FALSE;
5749 break;
5750 }
5751 else
5752 {
5753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5754 pAdapterNode = pNext;
5755 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 }
5757
5758 if (TRUE == enter_standby)
5759 {
5760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5761 "entering standby", __func__);
5762 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5763 {
5764 /*log and return success*/
5765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5766 "wlan in power save", __func__);
5767 }
5768 }
5769
5770 EXIT();
5771 return 0;
5772}
5773
5774/**---------------------------------------------------------------------------
5775
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305776 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005777
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305778 This is called in response to ifconfig down
5779
5780 \param - dev Pointer to net_device structure
5781
5782 \return - 0 for success non-zero for failure
5783-----------------------------------------------------------------------------*/
5784int hdd_stop (struct net_device *dev)
5785{
5786 int ret;
5787
5788 vos_ssr_protect(__func__);
5789 ret = __hdd_stop(dev);
5790 vos_ssr_unprotect(__func__);
5791
5792 return ret;
5793}
5794
5795/**---------------------------------------------------------------------------
5796
5797 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005798
5799 \param - dev Pointer to net_device structure
5800
5801 \return - void
5802
5803 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305804static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005805{
5806 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305807 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 ENTER();
5809
5810 do
5811 {
5812 if (NULL == pAdapter)
5813 {
5814 hddLog(VOS_TRACE_LEVEL_FATAL,
5815 "%s: NULL pAdapter", __func__);
5816 break;
5817 }
5818
5819 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5820 {
5821 hddLog(VOS_TRACE_LEVEL_FATAL,
5822 "%s: Invalid magic", __func__);
5823 break;
5824 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5826 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 {
5828 hddLog(VOS_TRACE_LEVEL_FATAL,
5829 "%s: NULL pHddCtx", __func__);
5830 break;
5831 }
5832
5833 if (dev != pAdapter->dev)
5834 {
5835 hddLog(VOS_TRACE_LEVEL_FATAL,
5836 "%s: Invalid device reference", __func__);
5837 /* we haven't validated all cases so let this go for now */
5838 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305839#ifdef FEATURE_WLAN_TDLS
5840 mutex_lock(&pHddCtx->tdls_lock);
5841#endif
c_hpothu002231a2015-02-05 14:58:51 +05305842 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305843#ifdef FEATURE_WLAN_TDLS
5844 mutex_unlock(&pHddCtx->tdls_lock);
5845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005846
5847 /* after uninit our adapter structure will no longer be valid */
5848 pAdapter->dev = NULL;
5849 pAdapter->magic = 0;
5850 } while (0);
5851
5852 EXIT();
5853}
5854
5855/**---------------------------------------------------------------------------
5856
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305857 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5858
5859 This is called during the netdev unregister to uninitialize all data
5860associated with the device
5861
5862 \param - dev Pointer to net_device structure
5863
5864 \return - void
5865
5866 --------------------------------------------------------------------------*/
5867static void hdd_uninit (struct net_device *dev)
5868{
5869 vos_ssr_protect(__func__);
5870 __hdd_uninit(dev);
5871 vos_ssr_unprotect(__func__);
5872}
5873
5874/**---------------------------------------------------------------------------
5875
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 \brief hdd_release_firmware() -
5877
5878 This function calls the release firmware API to free the firmware buffer.
5879
5880 \param - pFileName Pointer to the File Name.
5881 pCtx - Pointer to the adapter .
5882
5883
5884 \return - 0 for success, non zero for failure
5885
5886 --------------------------------------------------------------------------*/
5887
5888VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5889{
5890 VOS_STATUS status = VOS_STATUS_SUCCESS;
5891 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5892 ENTER();
5893
5894
5895 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5896
5897 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5898
5899 if(pHddCtx->fw) {
5900 release_firmware(pHddCtx->fw);
5901 pHddCtx->fw = NULL;
5902 }
5903 else
5904 status = VOS_STATUS_E_FAILURE;
5905 }
5906 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5907 if(pHddCtx->nv) {
5908 release_firmware(pHddCtx->nv);
5909 pHddCtx->nv = NULL;
5910 }
5911 else
5912 status = VOS_STATUS_E_FAILURE;
5913
5914 }
5915
5916 EXIT();
5917 return status;
5918}
5919
5920/**---------------------------------------------------------------------------
5921
5922 \brief hdd_request_firmware() -
5923
5924 This function reads the firmware file using the request firmware
5925 API and returns the the firmware data and the firmware file size.
5926
5927 \param - pfileName - Pointer to the file name.
5928 - pCtx - Pointer to the adapter .
5929 - ppfw_data - Pointer to the pointer of the firmware data.
5930 - pSize - Pointer to the file size.
5931
5932 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5933
5934 --------------------------------------------------------------------------*/
5935
5936
5937VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5938{
5939 int status;
5940 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5941 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5942 ENTER();
5943
5944 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5945
5946 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5947
5948 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5949 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5950 __func__, pfileName);
5951 retval = VOS_STATUS_E_FAILURE;
5952 }
5953
5954 else {
5955 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5956 *pSize = pHddCtx->fw->size;
5957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5958 __func__, *pSize);
5959 }
5960 }
5961 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5962
5963 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5964
5965 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5966 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5967 __func__, pfileName);
5968 retval = VOS_STATUS_E_FAILURE;
5969 }
5970
5971 else {
5972 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5973 *pSize = pHddCtx->nv->size;
5974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5975 __func__, *pSize);
5976 }
5977 }
5978
5979 EXIT();
5980 return retval;
5981}
5982/**---------------------------------------------------------------------------
5983 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5984
5985 This is the function invoked by SME to inform the result of a full power
5986 request issued by HDD
5987
5988 \param - callbackcontext - Pointer to cookie
5989 status - result of request
5990
5991 \return - None
5992
5993--------------------------------------------------------------------------*/
5994void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5995{
5996 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5997
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005998 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 if(&pHddCtx->full_pwr_comp_var)
6000 {
6001 complete(&pHddCtx->full_pwr_comp_var);
6002 }
6003}
6004
6005/**---------------------------------------------------------------------------
6006
6007 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
6008
6009 This is the function invoked by SME to inform the result of BMPS
6010 request issued by HDD
6011
6012 \param - callbackcontext - Pointer to cookie
6013 status - result of request
6014
6015 \return - None
6016
6017--------------------------------------------------------------------------*/
6018void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
6019{
6020
6021 struct completion *completion_var = (struct completion*) callbackContext;
6022
Arif Hussain6d2a3322013-11-17 19:50:10 -08006023 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 if(completion_var != NULL)
6025 {
6026 complete(completion_var);
6027 }
6028}
6029
6030/**---------------------------------------------------------------------------
6031
6032 \brief hdd_get_cfg_file_size() -
6033
6034 This function reads the configuration file using the request firmware
6035 API and returns the configuration file size.
6036
6037 \param - pCtx - Pointer to the adapter .
6038 - pFileName - Pointer to the file name.
6039 - pBufSize - Pointer to the buffer size.
6040
6041 \return - 0 for success, non zero for failure
6042
6043 --------------------------------------------------------------------------*/
6044
6045VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6046{
6047 int status;
6048 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6049
6050 ENTER();
6051
6052 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6053
6054 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6055 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6056 status = VOS_STATUS_E_FAILURE;
6057 }
6058 else {
6059 *pBufSize = pHddCtx->fw->size;
6060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6061 release_firmware(pHddCtx->fw);
6062 pHddCtx->fw = NULL;
6063 }
6064
6065 EXIT();
6066 return VOS_STATUS_SUCCESS;
6067}
6068
6069/**---------------------------------------------------------------------------
6070
6071 \brief hdd_read_cfg_file() -
6072
6073 This function reads the configuration file using the request firmware
6074 API and returns the cfg data and the buffer size of the configuration file.
6075
6076 \param - pCtx - Pointer to the adapter .
6077 - pFileName - Pointer to the file name.
6078 - pBuffer - Pointer to the data buffer.
6079 - pBufSize - Pointer to the buffer size.
6080
6081 \return - 0 for success, non zero for failure
6082
6083 --------------------------------------------------------------------------*/
6084
6085VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6086 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6087{
6088 int status;
6089 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6090
6091 ENTER();
6092
6093 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6094
6095 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6097 return VOS_STATUS_E_FAILURE;
6098 }
6099 else {
6100 if(*pBufSize != pHddCtx->fw->size) {
6101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6102 "file size", __func__);
6103 release_firmware(pHddCtx->fw);
6104 pHddCtx->fw = NULL;
6105 return VOS_STATUS_E_FAILURE;
6106 }
6107 else {
6108 if(pBuffer) {
6109 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6110 }
6111 release_firmware(pHddCtx->fw);
6112 pHddCtx->fw = NULL;
6113 }
6114 }
6115
6116 EXIT();
6117
6118 return VOS_STATUS_SUCCESS;
6119}
6120
6121/**---------------------------------------------------------------------------
6122
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306123 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006124
6125 This function sets the user specified mac address using
6126 the command ifconfig wlanX hw ether <mac adress>.
6127
6128 \param - dev - Pointer to the net device.
6129 - addr - Pointer to the sockaddr.
6130 \return - 0 for success, non zero for failure
6131
6132 --------------------------------------------------------------------------*/
6133
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306134static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006135{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306136 hdd_adapter_t *pAdapter;
6137 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 struct sockaddr *psta_mac_addr = addr;
6139 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306140 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006141
6142 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306143 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6144 if (NULL == pAdapter)
6145 {
6146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6147 "%s: Adapter is NULL",__func__);
6148 return -EINVAL;
6149 }
6150 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6151 ret = wlan_hdd_validate_context(pHddCtx);
6152 if (0 != ret)
6153 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306154 return ret;
6155 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006156
6157 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6159
6160 EXIT();
6161 return halStatus;
6162}
6163
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306164/**---------------------------------------------------------------------------
6165
6166 \brief hdd_set_mac_address() -
6167
6168 Wrapper function to protect __hdd_set_mac_address() function from ssr
6169
6170 \param - dev - Pointer to the net device.
6171 - addr - Pointer to the sockaddr.
6172 \return - 0 for success, non zero for failure
6173
6174 --------------------------------------------------------------------------*/
6175static int hdd_set_mac_address(struct net_device *dev, void *addr)
6176{
6177 int ret;
6178
6179 vos_ssr_protect(__func__);
6180 ret = __hdd_set_mac_address(dev, addr);
6181 vos_ssr_unprotect(__func__);
6182
6183 return ret;
6184}
6185
Jeff Johnson295189b2012-06-20 16:38:30 -07006186tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6187{
6188 int i;
6189 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6190 {
Abhishek Singheb183782014-02-06 13:37:21 +05306191 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 break;
6193 }
6194
6195 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6196 return NULL;
6197
6198 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6199 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6200}
6201
6202void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6203{
6204 int i;
6205 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6206 {
6207 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6208 {
6209 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6210 break;
6211 }
6212 }
6213 return;
6214}
6215
6216#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6217 static struct net_device_ops wlan_drv_ops = {
6218 .ndo_open = hdd_open,
6219 .ndo_stop = hdd_stop,
6220 .ndo_uninit = hdd_uninit,
6221 .ndo_start_xmit = hdd_hard_start_xmit,
6222 .ndo_tx_timeout = hdd_tx_timeout,
6223 .ndo_get_stats = hdd_stats,
6224 .ndo_do_ioctl = hdd_ioctl,
6225 .ndo_set_mac_address = hdd_set_mac_address,
6226 .ndo_select_queue = hdd_select_queue,
6227#ifdef WLAN_FEATURE_PACKET_FILTERING
6228#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6229 .ndo_set_rx_mode = hdd_set_multicast_list,
6230#else
6231 .ndo_set_multicast_list = hdd_set_multicast_list,
6232#endif //LINUX_VERSION_CODE
6233#endif
6234 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006235 static struct net_device_ops wlan_mon_drv_ops = {
6236 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306237 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 .ndo_uninit = hdd_uninit,
6239 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6240 .ndo_tx_timeout = hdd_tx_timeout,
6241 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306242 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 .ndo_set_mac_address = hdd_set_mac_address,
6244 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306245
Jeff Johnson295189b2012-06-20 16:38:30 -07006246#endif
6247
6248void hdd_set_station_ops( struct net_device *pWlanDev )
6249{
6250#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 pWlanDev->netdev_ops = &wlan_drv_ops;
6252#else
6253 pWlanDev->open = hdd_open;
6254 pWlanDev->stop = hdd_stop;
6255 pWlanDev->uninit = hdd_uninit;
6256 pWlanDev->hard_start_xmit = NULL;
6257 pWlanDev->tx_timeout = hdd_tx_timeout;
6258 pWlanDev->get_stats = hdd_stats;
6259 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 pWlanDev->set_mac_address = hdd_set_mac_address;
6261#endif
6262}
6263
Katya Nigam1fd24402015-02-16 14:52:19 +05306264void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6265{
6266 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6267 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6268 #else
6269 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6270 #endif
6271}
6272
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006273static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006274{
6275 struct net_device *pWlanDev = NULL;
6276 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 /*
6278 * cfg80211 initialization and registration....
6279 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306280 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6282 NET_NAME_UNKNOWN,
6283#endif
6284 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 if(pWlanDev != NULL)
6286 {
6287
6288 //Save the pointer to the net_device in the HDD adapter
6289 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6292
6293 pAdapter->dev = pWlanDev;
6294 pAdapter->pHddCtx = pHddCtx;
6295 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306296 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006297
Rajeev79dbe4c2013-10-05 11:03:42 +05306298#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05306299 pAdapter->pBatchScanRsp = NULL;
6300 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006301 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006302 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306303 mutex_init(&pAdapter->hdd_batch_scan_lock);
6304#endif
6305
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 pAdapter->isLinkUpSvcNeeded = FALSE;
6307 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6308 //Init the net_device structure
6309 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6310
6311 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6312 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6313 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6314 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6315
6316 hdd_set_station_ops( pAdapter->dev );
6317
6318 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6320 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6321 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 /* set pWlanDev's parent to underlying device */
6323 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006324
6325 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 }
6327
6328 return pAdapter;
6329}
6330
6331VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6332{
6333 struct net_device *pWlanDev = pAdapter->dev;
6334 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6335 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6336 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6337
6338 if( rtnl_lock_held )
6339 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006340 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6342 {
6343 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6344 return VOS_STATUS_E_FAILURE;
6345 }
6346 }
6347 if (register_netdevice(pWlanDev))
6348 {
6349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6350 return VOS_STATUS_E_FAILURE;
6351 }
6352 }
6353 else
6354 {
6355 if(register_netdev(pWlanDev))
6356 {
6357 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6358 return VOS_STATUS_E_FAILURE;
6359 }
6360 }
6361 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6362
6363 return VOS_STATUS_SUCCESS;
6364}
6365
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006366static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006367{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006368 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006369
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006370 if (NULL == pAdapter)
6371 {
6372 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6373 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006375
6376 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6377 {
6378 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6379 return eHAL_STATUS_NOT_INITIALIZED;
6380 }
6381
6382 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6383
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006384#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006385 /* need to make sure all of our scheduled work has completed.
6386 * This callback is called from MC thread context, so it is safe to
6387 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006388 *
6389 * Even though this is called from MC thread context, if there is a faulty
6390 * work item in the system, that can hang this call forever. So flushing
6391 * this global work queue is not safe; and now we make sure that
6392 * individual work queues are stopped correctly. But the cancel work queue
6393 * is a GPL only API, so the proprietary version of the driver would still
6394 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006395 */
6396 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006397#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006398
6399 /* We can be blocked while waiting for scheduled work to be
6400 * flushed, and the adapter structure can potentially be freed, in
6401 * which case the magic will have been reset. So make sure the
6402 * magic is still good, and hence the adapter structure is still
6403 * valid, before signaling completion */
6404 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6405 {
6406 complete(&pAdapter->session_close_comp_var);
6407 }
6408
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 return eHAL_STATUS_SUCCESS;
6410}
6411
6412VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6413{
6414 struct net_device *pWlanDev = pAdapter->dev;
6415 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6417 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6418 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306419 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006420
Nirav Shah7e3c8132015-06-22 23:51:42 +05306421 spin_lock_init( &pAdapter->sta_hash_lock);
6422 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6423
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006425 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 //Open a SME session for future operation
6427 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006428 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6430 {
6431 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006432 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 halStatus, halStatus );
6434 status = VOS_STATUS_E_FAILURE;
6435 goto error_sme_open;
6436 }
6437
6438 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306439 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 &pAdapter->session_open_comp_var,
6441 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306442 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
6444 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306445 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 status = VOS_STATUS_E_FAILURE;
6447 goto error_sme_open;
6448 }
6449
6450 // Register wireless extensions
6451 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6452 {
6453 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006454 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 halStatus, halStatus );
6456 status = VOS_STATUS_E_FAILURE;
6457 goto error_register_wext;
6458 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306459
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306461 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6462 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6463 #else
6464 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6465 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006466
6467 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306468 hddLog(VOS_TRACE_LEVEL_INFO,
6469 "%s: Set HDD connState to eConnectionState_NotConnected",
6470 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6472
6473 //Set the default operation channel
6474 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6475
6476 /* Make the default Auth Type as OPEN*/
6477 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6478
6479 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6480 {
6481 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006482 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 status, status );
6484 goto error_init_txrx;
6485 }
6486
6487 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6488
6489 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6490 {
6491 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006492 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 status, status );
6494 goto error_wmm_init;
6495 }
6496
6497 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6498
6499 return VOS_STATUS_SUCCESS;
6500
6501error_wmm_init:
6502 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6503 hdd_deinit_tx_rx(pAdapter);
6504error_init_txrx:
6505 hdd_UnregisterWext(pWlanDev);
6506error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006507 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006508 {
6509 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006510 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306511 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006512 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306514 unsigned long rc;
6515
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306517 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006519 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306520 if (rc <= 0)
6521 hddLog(VOS_TRACE_LEVEL_ERROR,
6522 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 }
6524}
6525error_sme_open:
6526 return status;
6527}
6528
Jeff Johnson295189b2012-06-20 16:38:30 -07006529void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6530{
6531 hdd_cfg80211_state_t *cfgState;
6532
6533 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6534
6535 if( NULL != cfgState->buf )
6536 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306537 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6539 rc = wait_for_completion_interruptible_timeout(
6540 &pAdapter->tx_action_cnf_event,
6541 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306542 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6545 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6546 , __func__, rc);
6547
6548 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6549 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 }
6551 }
6552 return;
6553}
Jeff Johnson295189b2012-06-20 16:38:30 -07006554
c_hpothu002231a2015-02-05 14:58:51 +05306555void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006556{
6557 ENTER();
6558 switch ( pAdapter->device_mode )
6559 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306560 case WLAN_HDD_IBSS:
6561 {
6562 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6563 {
6564 hdd_ibss_deinit_tx_rx( pAdapter );
6565 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6566 }
6567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 case WLAN_HDD_INFRA_STATION:
6569 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006570 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 {
6572 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6573 {
6574 hdd_deinit_tx_rx( pAdapter );
6575 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6576 }
6577
6578 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6579 {
6580 hdd_wmm_adapter_close( pAdapter );
6581 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6582 }
6583
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 break;
6586 }
6587
6588 case WLAN_HDD_SOFTAP:
6589 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306591
6592 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6593 {
6594 hdd_wmm_adapter_close( pAdapter );
6595 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6596 }
6597
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006599
c_hpothu002231a2015-02-05 14:58:51 +05306600 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006602 break;
6603 }
6604
6605 case WLAN_HDD_MONITOR:
6606 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6608 {
6609 hdd_deinit_tx_rx( pAdapter );
6610 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 break;
6613 }
6614
6615
6616 default:
6617 break;
6618 }
6619
6620 EXIT();
6621}
6622
6623void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6624{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006625 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306626
6627 ENTER();
6628 if (NULL == pAdapter)
6629 {
6630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6631 "%s: HDD adapter is Null", __func__);
6632 return;
6633 }
6634
6635 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006636
Rajeev79dbe4c2013-10-05 11:03:42 +05306637#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306638 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6639 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006640 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306641 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6642 )
6643 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006644 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306645 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006646 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6647 {
6648 hdd_deinit_batch_scan(pAdapter);
6649 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306650 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006651 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306652#endif
6653
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6655 if( rtnl_held )
6656 {
6657 unregister_netdevice(pWlanDev);
6658 }
6659 else
6660 {
6661 unregister_netdev(pWlanDev);
6662 }
6663 // note that the pAdapter is no longer valid at this point
6664 // since the memory has been reclaimed
6665 }
6666
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306667 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006668}
6669
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006670void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6671{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306672 VOS_STATUS status;
6673 hdd_adapter_t *pAdapter = NULL;
6674 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006675
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306676 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006677
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306678 /*loop through all adapters.*/
6679 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006680 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306681 pAdapter = pAdapterNode->pAdapter;
6682 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6683 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006684
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306685 { // we skip this registration for modes other than STA and P2P client modes.
6686 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6687 pAdapterNode = pNext;
6688 continue;
6689 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006690
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306691 //Apply Dynamic DTIM For P2P
6692 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6693 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6694 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6695 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6696 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6697 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6698 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6699 (eConnectionState_Associated ==
6700 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6701 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6702 {
6703 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006704
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306705 powerRequest.uIgnoreDTIM = 1;
6706 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6707
6708 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6709 {
6710 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6711 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6712 }
6713 else
6714 {
6715 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6716 }
6717
6718 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6719 * specified during Enter/Exit BMPS when LCD off*/
6720 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6721 NULL, eANI_BOOLEAN_FALSE);
6722 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6723 NULL, eANI_BOOLEAN_FALSE);
6724
6725 /* switch to the DTIM specified in cfg.ini */
6726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05306727 "Switch to DTIM %d Listen interval %d",
6728 powerRequest.uDTIMPeriod,
6729 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306730 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6731 break;
6732
6733 }
6734
6735 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6736 pAdapterNode = pNext;
6737 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006738}
6739
6740void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6741{
6742 /*Switch back to DTIM 1*/
6743 tSirSetPowerParamsReq powerRequest = { 0 };
6744
6745 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6746 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006747 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006748
6749 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6750 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6751 NULL, eANI_BOOLEAN_FALSE);
6752 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6753 NULL, eANI_BOOLEAN_FALSE);
6754
6755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6756 "Switch to DTIM%d",powerRequest.uListenInterval);
6757 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6758
6759}
6760
Jeff Johnson295189b2012-06-20 16:38:30 -07006761VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6762{
6763 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306764 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6765 {
6766 hddLog( LOGE, FL("Wlan Unload in progress"));
6767 return VOS_STATUS_E_PERM;
6768 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6770 {
6771 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6772 }
6773
6774 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6775 {
6776 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6777 }
6778
6779 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6780 {
6781 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6782 }
6783
6784 return status;
6785}
6786
6787VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6788{
6789 hdd_adapter_t *pAdapter = NULL;
6790 eHalStatus halStatus;
6791 VOS_STATUS status = VOS_STATUS_E_INVAL;
6792 v_BOOL_t disableBmps = FALSE;
6793 v_BOOL_t disableImps = FALSE;
6794
6795 switch(session_type)
6796 {
6797 case WLAN_HDD_INFRA_STATION:
6798 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 case WLAN_HDD_P2P_CLIENT:
6800 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 //Exit BMPS -> Is Sta/P2P Client is already connected
6802 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6803 if((NULL != pAdapter)&&
6804 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6805 {
6806 disableBmps = TRUE;
6807 }
6808
6809 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6810 if((NULL != pAdapter)&&
6811 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6812 {
6813 disableBmps = TRUE;
6814 }
6815
6816 //Exit both Bmps and Imps incase of Go/SAP Mode
6817 if((WLAN_HDD_SOFTAP == session_type) ||
6818 (WLAN_HDD_P2P_GO == session_type))
6819 {
6820 disableBmps = TRUE;
6821 disableImps = TRUE;
6822 }
6823
6824 if(TRUE == disableImps)
6825 {
6826 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6827 {
6828 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6829 }
6830 }
6831
6832 if(TRUE == disableBmps)
6833 {
6834 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6835 {
6836 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6837
6838 if(eHAL_STATUS_SUCCESS != halStatus)
6839 {
6840 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006841 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 VOS_ASSERT(0);
6843 return status;
6844 }
6845 }
6846
6847 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6848 {
6849 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6850
6851 if(eHAL_STATUS_SUCCESS != halStatus)
6852 {
6853 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006854 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 VOS_ASSERT(0);
6856 return status;
6857 }
6858 }
6859 }
6860
6861 if((TRUE == disableBmps) ||
6862 (TRUE == disableImps))
6863 {
6864 /* Now, get the chip into Full Power now */
6865 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6866 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6867 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6868
6869 if(halStatus != eHAL_STATUS_SUCCESS)
6870 {
6871 if(halStatus == eHAL_STATUS_PMC_PENDING)
6872 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306873 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306875 ret = wait_for_completion_interruptible_timeout(
6876 &pHddCtx->full_pwr_comp_var,
6877 msecs_to_jiffies(1000));
6878 if (ret <= 0)
6879 {
6880 hddLog(VOS_TRACE_LEVEL_ERROR,
6881 "%s: wait on full_pwr_comp_var failed %ld",
6882 __func__, ret);
6883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 }
6885 else
6886 {
6887 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006888 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 VOS_ASSERT(0);
6890 return status;
6891 }
6892 }
6893
6894 status = VOS_STATUS_SUCCESS;
6895 }
6896
6897 break;
6898 }
6899 return status;
6900}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05306901
6902void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6903{
6904 if (magic == NULL || cmpVar == NULL) {
6905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6906 FL("invalid arguments %p %p"), magic, cmpVar);
6907 return;
6908 }
6909 if (*magic != MON_MODE_MSG_MAGIC) {
6910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6911 FL("maic: %x"), *magic);
6912 return;
6913 }
6914
6915 complete(cmpVar);
6916 return;
6917}
6918
Katya Nigame7b69a82015-04-28 15:24:06 +05306919void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6920 {
6921 hdd_mon_ctx_t *pMonCtx = NULL;
6922 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6923
6924 pMonCtx->state = 0;
6925 pMonCtx->ChannelNo = 1;
6926 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306927 pMonCtx->crcCheckEnabled = 1;
6928 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6929 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306930 pMonCtx->numOfMacFilters = 0;
6931 }
6932
Jeff Johnson295189b2012-06-20 16:38:30 -07006933
6934hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006935 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 tANI_U8 rtnl_held )
6937{
6938 hdd_adapter_t *pAdapter = NULL;
6939 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6940 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6941 VOS_STATUS exitbmpsStatus;
6942
Arif Hussain6d2a3322013-11-17 19:50:10 -08006943 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006944
Nirav Shah436658f2014-02-28 17:05:45 +05306945 if(macAddr == NULL)
6946 {
6947 /* Not received valid macAddr */
6948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6949 "%s:Unable to add virtual intf: Not able to get"
6950 "valid mac address",__func__);
6951 return NULL;
6952 }
6953
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 //Disable BMPS incase of Concurrency
6955 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6956
6957 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6958 {
6959 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306960 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 VOS_ASSERT(0);
6962 return NULL;
6963 }
6964
6965 switch(session_type)
6966 {
6967 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006969 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 {
6971 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6972
6973 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306974 {
6975 hddLog(VOS_TRACE_LEVEL_FATAL,
6976 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306978 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006979
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306980#ifdef FEATURE_WLAN_TDLS
6981 /* A Mutex Lock is introduced while changing/initializing the mode to
6982 * protect the concurrent access for the Adapters by TDLS module.
6983 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306984 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306985#endif
6986
Jeff Johnsone7245742012-09-05 17:12:55 -07006987 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6988 NL80211_IFTYPE_P2P_CLIENT:
6989 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006990
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306992#ifdef FEATURE_WLAN_TDLS
6993 mutex_unlock(&pHddCtx->tdls_lock);
6994#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306995
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05306996 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05306997 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 if( VOS_STATUS_SUCCESS != status )
6999 goto err_free_netdev;
7000
7001 status = hdd_register_interface( pAdapter, rtnl_held );
7002 if( VOS_STATUS_SUCCESS != status )
7003 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307004#ifdef FEATURE_WLAN_TDLS
7005 mutex_lock(&pHddCtx->tdls_lock);
7006#endif
c_hpothu002231a2015-02-05 14:58:51 +05307007 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307008#ifdef FEATURE_WLAN_TDLS
7009 mutex_unlock(&pHddCtx->tdls_lock);
7010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 goto err_free_netdev;
7012 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307013
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307014 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307015 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307016
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307017#ifdef WLAN_NS_OFFLOAD
7018 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307019 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307020#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007021 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307022 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 netif_tx_disable(pAdapter->dev);
7024 //netif_tx_disable(pWlanDev);
7025 netif_carrier_off(pAdapter->dev);
7026
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307027 if (WLAN_HDD_P2P_CLIENT == session_type ||
7028 WLAN_HDD_P2P_DEVICE == session_type)
7029 {
7030 /* Initialize the work queue to defer the
7031 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307032 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307033 hdd_p2p_roc_work_queue);
7034 }
7035
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 break;
7037 }
7038
Jeff Johnson295189b2012-06-20 16:38:30 -07007039 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 case WLAN_HDD_SOFTAP:
7041 {
7042 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7043 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307044 {
7045 hddLog(VOS_TRACE_LEVEL_FATAL,
7046 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007049
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7051 NL80211_IFTYPE_AP:
7052 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 pAdapter->device_mode = session_type;
7054
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307055 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 status = hdd_init_ap_mode(pAdapter);
7057 if( VOS_STATUS_SUCCESS != status )
7058 goto err_free_netdev;
7059
Nirav Shah7e3c8132015-06-22 23:51:42 +05307060 status = hdd_sta_id_hash_attach(pAdapter);
7061 if (VOS_STATUS_SUCCESS != status)
7062 {
7063 hddLog(VOS_TRACE_LEVEL_FATAL,
7064 FL("failed to attach hash for session %d"), session_type);
7065 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7066 goto err_free_netdev;
7067 }
7068
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 status = hdd_register_hostapd( pAdapter, rtnl_held );
7070 if( VOS_STATUS_SUCCESS != status )
7071 {
c_hpothu002231a2015-02-05 14:58:51 +05307072 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 goto err_free_netdev;
7074 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 netif_tx_disable(pAdapter->dev);
7077 netif_carrier_off(pAdapter->dev);
7078
7079 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307080
7081 if (WLAN_HDD_P2P_GO == session_type)
7082 {
7083 /* Initialize the work queue to
7084 * defer the back to back RoC request */
7085 INIT_DELAYED_WORK(&pAdapter->roc_work,
7086 hdd_p2p_roc_work_queue);
7087 }
Bhargav Shahd0715912015-10-01 18:17:37 +05307088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 break;
7090 }
7091 case WLAN_HDD_MONITOR:
7092 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7094 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307095 {
7096 hddLog(VOS_TRACE_LEVEL_FATAL,
7097 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007100
Katya Nigame7b69a82015-04-28 15:24:06 +05307101 // Register wireless extensions
7102 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7103 {
7104 hddLog(VOS_TRACE_LEVEL_FATAL,
7105 "hdd_register_wext() failed with status code %08d [x%08x]",
7106 status, status );
7107 status = VOS_STATUS_E_FAILURE;
7108 }
7109
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7111 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007112#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7113 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7114#else
7115 pAdapter->dev->open = hdd_mon_open;
7116 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307117 pAdapter->dev->stop = hdd_mon_stop;
7118 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007119#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307120 status = hdd_register_interface( pAdapter, rtnl_held );
7121 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307122 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007123 hdd_init_tx_rx( pAdapter );
7124 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307125 //Stop the Interface TX queue.
7126 netif_tx_disable(pAdapter->dev);
7127 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 }
7129 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 case WLAN_HDD_FTM:
7131 {
7132 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7133
7134 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307135 {
7136 hddLog(VOS_TRACE_LEVEL_FATAL,
7137 FL("failed to allocate adapter for session %d"), session_type);
7138 return NULL;
7139 }
7140
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7142 * message while loading driver in FTM mode. */
7143 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7144 pAdapter->device_mode = session_type;
7145 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307146
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307147 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307148 hdd_init_tx_rx( pAdapter );
7149
7150 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307151 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307152 netif_tx_disable(pAdapter->dev);
7153 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 }
7155 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 default:
7157 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307158 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7159 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 VOS_ASSERT(0);
7161 return NULL;
7162 }
7163 }
7164
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 if( VOS_STATUS_SUCCESS == status )
7166 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307167 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7169 if( NULL == pHddAdapterNode )
7170 {
7171 status = VOS_STATUS_E_NOMEM;
7172 }
7173 else
7174 {
7175 pHddAdapterNode->pAdapter = pAdapter;
7176 status = hdd_add_adapter_back ( pHddCtx,
7177 pHddAdapterNode );
7178 }
7179 }
7180
7181 if( VOS_STATUS_SUCCESS != status )
7182 {
7183 if( NULL != pAdapter )
7184 {
7185 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7186 pAdapter = NULL;
7187 }
7188 if( NULL != pHddAdapterNode )
7189 {
7190 vos_mem_free( pHddAdapterNode );
7191 }
7192
7193 goto resume_bmps;
7194 }
7195
7196 if(VOS_STATUS_SUCCESS == status)
7197 {
7198 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7199
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007200 //Initialize the WoWL service
7201 if(!hdd_init_wowl(pAdapter))
7202 {
7203 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7204 goto err_free_netdev;
7205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 return pAdapter;
7208
7209err_free_netdev:
7210 free_netdev(pAdapter->dev);
7211 wlan_hdd_release_intf_addr( pHddCtx,
7212 pAdapter->macAddressCurrent.bytes );
7213
7214resume_bmps:
7215 //If bmps disabled enable it
7216 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7217 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307218 if (pHddCtx->hdd_wlan_suspended)
7219 {
7220 hdd_set_pwrparams(pHddCtx);
7221 }
7222 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 }
7224 return NULL;
7225}
7226
7227VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7228 tANI_U8 rtnl_held )
7229{
7230 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7231 VOS_STATUS status;
7232
7233 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7234 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307235 {
7236 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7237 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007240
7241 while ( pCurrent->pAdapter != pAdapter )
7242 {
7243 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7244 if( VOS_STATUS_SUCCESS != status )
7245 break;
7246
7247 pCurrent = pNext;
7248 }
7249 pAdapterNode = pCurrent;
7250 if( VOS_STATUS_SUCCESS == status )
7251 {
7252 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7253 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307254
7255#ifdef FEATURE_WLAN_TDLS
7256
7257 /* A Mutex Lock is introduced while changing/initializing the mode to
7258 * protect the concurrent access for the Adapters by TDLS module.
7259 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307260 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307261#endif
7262
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 hdd_remove_adapter( pHddCtx, pAdapterNode );
7264 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007265 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007266
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307267#ifdef FEATURE_WLAN_TDLS
7268 mutex_unlock(&pHddCtx->tdls_lock);
7269#endif
7270
Jeff Johnson295189b2012-06-20 16:38:30 -07007271
7272 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307273 if ((!vos_concurrent_open_sessions_running()) &&
7274 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7275 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307277 if (pHddCtx->hdd_wlan_suspended)
7278 {
7279 hdd_set_pwrparams(pHddCtx);
7280 }
7281 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 }
7283
7284 return VOS_STATUS_SUCCESS;
7285 }
7286
7287 return VOS_STATUS_E_FAILURE;
7288}
7289
7290VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7291{
7292 hdd_adapter_list_node_t *pHddAdapterNode;
7293 VOS_STATUS status;
7294
7295 ENTER();
7296
7297 do
7298 {
7299 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7300 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7301 {
7302 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7303 vos_mem_free( pHddAdapterNode );
7304 }
7305 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7306
7307 EXIT();
7308
7309 return VOS_STATUS_SUCCESS;
7310}
7311
7312void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7313{
7314 v_U8_t addIE[1] = {0};
7315
7316 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7317 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7318 eANI_BOOLEAN_FALSE) )
7319 {
7320 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007321 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 }
7323
7324 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7325 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7326 eANI_BOOLEAN_FALSE) )
7327 {
7328 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007329 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007330 }
7331
7332 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7333 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7334 eANI_BOOLEAN_FALSE) )
7335 {
7336 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007337 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007338 }
7339}
7340
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307341VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7342 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007343{
7344 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7345 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307346 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307348 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307349 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307350 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007351
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307352 if (pHddCtx->isLogpInProgress) {
7353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7354 "%s:LOGP in Progress. Ignore!!!",__func__);
7355 return VOS_STATUS_E_FAILURE;
7356 }
7357
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307359
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307360 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 switch(pAdapter->device_mode)
7362 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05307363 case WLAN_HDD_IBSS:
7364 if ( VOS_TRUE == bCloseSession )
7365 {
7366 status = hdd_sta_id_hash_detach(pAdapter);
7367 if (status != VOS_STATUS_SUCCESS)
7368 hddLog(VOS_TRACE_LEVEL_ERROR,
7369 FL("sta id hash detach failed"));
7370 }
7371
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 case WLAN_HDD_INFRA_STATION:
7373 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007374 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307375 {
7376 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307377#ifdef FEATURE_WLAN_TDLS
7378 mutex_lock(&pHddCtx->tdls_lock);
7379 wlan_hdd_tdls_exit(pAdapter, TRUE);
7380 mutex_unlock(&pHddCtx->tdls_lock);
7381#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307382 if( hdd_connIsConnected(pstation) ||
7383 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007384 {
7385 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7386 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7387 pAdapter->sessionId,
7388 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7389 else
7390 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7391 pAdapter->sessionId,
7392 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7393 //success implies disconnect command got queued up successfully
7394 if(halStatus == eHAL_STATUS_SUCCESS)
7395 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307396 ret = wait_for_completion_interruptible_timeout(
7397 &pAdapter->disconnect_comp_var,
7398 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7399 if (ret <= 0)
7400 {
7401 hddLog(VOS_TRACE_LEVEL_ERROR,
7402 "%s: wait on disconnect_comp_var failed %ld",
7403 __func__, ret);
7404 }
7405 }
7406 else
7407 {
7408 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7409 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 }
7411 memset(&wrqu, '\0', sizeof(wrqu));
7412 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7413 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7414 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7415 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307416 else if(pstation->conn_info.connState ==
7417 eConnectionState_Disconnecting)
7418 {
7419 ret = wait_for_completion_interruptible_timeout(
7420 &pAdapter->disconnect_comp_var,
7421 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7422 if (ret <= 0)
7423 {
7424 hddLog(VOS_TRACE_LEVEL_ERROR,
7425 FL("wait on disconnect_comp_var failed %ld"), ret);
7426 }
7427 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307428 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307430 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307431 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307433 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7434 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307435 {
7436 while (pAdapter->is_roc_inprogress)
7437 {
7438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7439 "%s: ROC in progress for session %d!!!",
7440 __func__, pAdapter->sessionId);
7441 // waiting for ROC to expire
7442 msleep(500);
7443 /* In GO present case , if retry exceeds 3,
7444 it means something went wrong. */
7445 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7446 {
7447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7448 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307449 if (eHAL_STATUS_SUCCESS !=
7450 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7451 pAdapter->sessionId ))
7452 {
7453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7454 FL("Failed to Cancel Remain on Channel"));
7455 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307456 wait_for_completion_interruptible_timeout(
7457 &pAdapter->cancel_rem_on_chan_var,
7458 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7459 break;
7460 }
7461 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307462 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307463 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307464#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307465 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307466#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307467
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307468 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307469
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307470 /* It is possible that the caller of this function does not
7471 * wish to close the session
7472 */
7473 if (VOS_TRUE == bCloseSession &&
7474 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007475 {
7476 INIT_COMPLETION(pAdapter->session_close_comp_var);
7477 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307478 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307479 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307481 unsigned long ret;
7482
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307484 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307485 &pAdapter->session_close_comp_var,
7486 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307487 if ( 0 >= ret)
7488 {
7489 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307490 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007492 }
7493 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 break;
7496
7497 case WLAN_HDD_SOFTAP:
7498 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05307499 if ( VOS_TRUE == bCloseSession )
7500 {
7501 status = hdd_sta_id_hash_detach(pAdapter);
7502 if (status != VOS_STATUS_SUCCESS)
7503 hddLog(VOS_TRACE_LEVEL_ERROR,
7504 FL("sta id hash detach failed"));
7505 }
7506
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307508 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7509 while (pAdapter->is_roc_inprogress) {
7510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7511 "%s: ROC in progress for session %d!!!",
7512 __func__, pAdapter->sessionId);
7513 msleep(500);
7514 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7516 "%s: ROC completion is not received.!!!", __func__);
7517 WLANSAP_CancelRemainOnChannel(
7518 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7519 wait_for_completion_interruptible_timeout(
7520 &pAdapter->cancel_rem_on_chan_var,
7521 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7522 break;
7523 }
7524 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307525
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307526 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307527 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007528 mutex_lock(&pHddCtx->sap_lock);
7529 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7530 {
7531 VOS_STATUS status;
7532 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7533
7534 //Stop Bss.
7535 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7536 if (VOS_IS_STATUS_SUCCESS(status))
7537 {
7538 hdd_hostapd_state_t *pHostapdState =
7539 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7540
7541 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7542
7543 if (!VOS_IS_STATUS_SUCCESS(status))
7544 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307545 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7546 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 }
7548 }
7549 else
7550 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007551 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 }
7553 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307554 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007555
7556 if (eHAL_STATUS_FAILURE ==
7557 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7558 0, NULL, eANI_BOOLEAN_FALSE))
7559 {
7560 hddLog(LOGE,
7561 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007562 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 }
7564
7565 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7566 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7567 eANI_BOOLEAN_FALSE) )
7568 {
7569 hddLog(LOGE,
7570 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7571 }
7572
7573 // Reset WNI_CFG_PROBE_RSP Flags
7574 wlan_hdd_reset_prob_rspies(pAdapter);
7575 kfree(pAdapter->sessionCtx.ap.beacon);
7576 pAdapter->sessionCtx.ap.beacon = NULL;
7577 }
7578 mutex_unlock(&pHddCtx->sap_lock);
7579 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007580
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 case WLAN_HDD_MONITOR:
7582 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007583
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 default:
7585 break;
7586 }
7587
7588 EXIT();
7589 return VOS_STATUS_SUCCESS;
7590}
7591
7592VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7593{
7594 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7595 VOS_STATUS status;
7596 hdd_adapter_t *pAdapter;
7597
7598 ENTER();
7599
7600 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7601
7602 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7603 {
7604 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007605
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307606 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007607
7608 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7609 pAdapterNode = pNext;
7610 }
7611
7612 EXIT();
7613
7614 return VOS_STATUS_SUCCESS;
7615}
7616
Rajeev Kumarf999e582014-01-09 17:33:29 -08007617
7618#ifdef FEATURE_WLAN_BATCH_SCAN
7619/**---------------------------------------------------------------------------
7620
7621 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7622 structures
7623
7624 \param - pAdapter Pointer to HDD adapter
7625
7626 \return - None
7627
7628 --------------------------------------------------------------------------*/
7629void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7630{
7631 tHddBatchScanRsp *pNode;
7632 tHddBatchScanRsp *pPrev;
7633
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307634 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007635 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307636 hddLog(VOS_TRACE_LEVEL_ERROR,
7637 "%s: Adapter context is Null", __func__);
7638 return;
7639 }
7640
7641 pNode = pAdapter->pBatchScanRsp;
7642 while (pNode)
7643 {
7644 pPrev = pNode;
7645 pNode = pNode->pNext;
7646 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007647 }
7648
7649 pAdapter->pBatchScanRsp = NULL;
7650 pAdapter->numScanList = 0;
7651 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7652 pAdapter->prev_batch_id = 0;
7653
7654 return;
7655}
7656#endif
7657
7658
Jeff Johnson295189b2012-06-20 16:38:30 -07007659VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7660{
7661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7662 VOS_STATUS status;
7663 hdd_adapter_t *pAdapter;
7664
7665 ENTER();
7666
7667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7668
7669 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7670 {
7671 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 netif_tx_disable(pAdapter->dev);
7674 netif_carrier_off(pAdapter->dev);
7675
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007676 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7677
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307679
Katya Nigam1fd24402015-02-16 14:52:19 +05307680 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7681 hdd_ibss_deinit_tx_rx(pAdapter);
7682
Nirav Shah7e3c8132015-06-22 23:51:42 +05307683 status = hdd_sta_id_hash_detach(pAdapter);
7684 if (status != VOS_STATUS_SUCCESS)
7685 hddLog(VOS_TRACE_LEVEL_ERROR,
7686 FL("sta id hash detach failed for session id %d"),
7687 pAdapter->sessionId);
7688
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307689 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7690
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307691 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7692 {
7693 hdd_wmm_adapter_close( pAdapter );
7694 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007696
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307697 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7698 {
7699 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7700 }
7701
Rajeev Kumarf999e582014-01-09 17:33:29 -08007702#ifdef FEATURE_WLAN_BATCH_SCAN
7703 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7704 {
7705 hdd_deinit_batch_scan(pAdapter);
7706 }
7707#endif
7708
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307709#ifdef FEATURE_WLAN_TDLS
7710 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307711 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307712 mutex_unlock(&pHddCtx->tdls_lock);
7713#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7715 pAdapterNode = pNext;
7716 }
7717
7718 EXIT();
7719
7720 return VOS_STATUS_SUCCESS;
7721}
7722
7723VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7724{
7725 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7726 VOS_STATUS status;
7727 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307728 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 ENTER();
7731
7732 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7733
7734 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7735 {
7736 pAdapter = pAdapterNode->pAdapter;
7737
Kumar Anand82c009f2014-05-29 00:29:42 -07007738 hdd_wmm_init( pAdapter );
7739
Jeff Johnson295189b2012-06-20 16:38:30 -07007740 switch(pAdapter->device_mode)
7741 {
7742 case WLAN_HDD_INFRA_STATION:
7743 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007744 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307745
7746 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7747
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 hdd_init_station_mode(pAdapter);
7749 /* Open the gates for HDD to receive Wext commands */
7750 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007751 pHddCtx->scan_info.mScanPending = FALSE;
7752 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007753
7754 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307755 if (!pHddCtx->isLogpInProgress)
7756 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007757
7758 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307759 if (eConnectionState_Associated == connState ||
7760 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 {
7762 union iwreq_data wrqu;
7763 memset(&wrqu, '\0', sizeof(wrqu));
7764 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7765 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7766 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007767 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007768
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 /* indicate disconnected event to nl80211 */
7770 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7771 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307773 else if (eConnectionState_Connecting == connState)
7774 {
7775 /*
7776 * Indicate connect failure to supplicant if we were in the
7777 * process of connecting
7778 */
7779 cfg80211_connect_result(pAdapter->dev, NULL,
7780 NULL, 0, NULL, 0,
7781 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7782 GFP_KERNEL);
7783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 break;
7785
7786 case WLAN_HDD_SOFTAP:
7787 /* softAP can handle SSR */
7788 break;
7789
7790 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007793 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 break;
7795
7796 case WLAN_HDD_MONITOR:
7797 /* monitor interface start */
7798 break;
7799 default:
7800 break;
7801 }
7802
7803 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7804 pAdapterNode = pNext;
7805 }
7806
7807 EXIT();
7808
7809 return VOS_STATUS_SUCCESS;
7810}
7811
7812VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7813{
7814 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7815 hdd_adapter_t *pAdapter;
7816 VOS_STATUS status;
7817 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307818 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007819
7820 ENTER();
7821
7822 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7823
7824 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7825 {
7826 pAdapter = pAdapterNode->pAdapter;
7827
7828 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7829 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7830 {
7831 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7832 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7833
Abhishek Singhf4669da2014-05-26 15:07:49 +05307834 hddLog(VOS_TRACE_LEVEL_INFO,
7835 "%s: Set HDD connState to eConnectionState_NotConnected",
7836 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307837 spin_lock_bh(&pAdapter->lock_for_active_session);
7838 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7839 {
7840 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7841 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307843 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 init_completion(&pAdapter->disconnect_comp_var);
7845 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7846 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7847
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307848 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007849 &pAdapter->disconnect_comp_var,
7850 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307851 if (0 >= ret)
7852 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7853 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854
7855 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7856 pHddCtx->isAmpAllowed = VOS_FALSE;
7857 sme_RoamConnect(pHddCtx->hHal,
7858 pAdapter->sessionId, &(pWextState->roamProfile),
7859 &roamId);
7860 }
7861
7862 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7863 pAdapterNode = pNext;
7864 }
7865
7866 EXIT();
7867
7868 return VOS_STATUS_SUCCESS;
7869}
7870
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007871void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7872{
7873 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7874 VOS_STATUS status;
7875 hdd_adapter_t *pAdapter;
7876 hdd_station_ctx_t *pHddStaCtx;
7877 hdd_ap_ctx_t *pHddApCtx;
7878 hdd_hostapd_state_t * pHostapdState;
7879 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7880 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7881 const char *p2pMode = "DEV";
7882 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007883
7884 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7885 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7886 {
7887 pAdapter = pAdapterNode->pAdapter;
7888 switch (pAdapter->device_mode) {
7889 case WLAN_HDD_INFRA_STATION:
7890 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7891 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7892 staChannel = pHddStaCtx->conn_info.operationChannel;
7893 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7894 }
7895 break;
7896 case WLAN_HDD_P2P_CLIENT:
7897 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7898 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7899 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7900 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7901 p2pMode = "CLI";
7902 }
7903 break;
7904 case WLAN_HDD_P2P_GO:
7905 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7906 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7907 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7908 p2pChannel = pHddApCtx->operatingChannel;
7909 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7910 }
7911 p2pMode = "GO";
7912 break;
7913 case WLAN_HDD_SOFTAP:
7914 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7915 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7916 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7917 apChannel = pHddApCtx->operatingChannel;
7918 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7919 }
7920 break;
7921 default:
7922 break;
7923 }
7924 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7925 pAdapterNode = pNext;
7926 }
7927 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7928 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7929 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307930 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007931 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7932 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307933 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007934 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7935 }
7936 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307937 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007938 apChannel, MAC_ADDR_ARRAY(apBssid));
7939 }
7940
7941 if (p2pChannel > 0 && apChannel > 0) {
7942 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7943 }
7944}
7945
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007946bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007947{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007948 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007949}
7950
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007951/* Once SSR is disabled then it cannot be set. */
7952void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007953{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007954 if (HDD_SSR_DISABLED == isSsrRequired)
7955 return;
7956
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 isSsrRequired = value;
7958}
7959
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307960void hdd_set_pre_close( hdd_context_t *pHddCtx)
7961{
7962 sme_PreClose(pHddCtx->hHal);
7963}
7964
Jeff Johnson295189b2012-06-20 16:38:30 -07007965VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7966 hdd_adapter_list_node_t** ppAdapterNode)
7967{
7968 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307969 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7971 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307972 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007973 return status;
7974}
7975
7976VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7977 hdd_adapter_list_node_t* pAdapterNode,
7978 hdd_adapter_list_node_t** pNextAdapterNode)
7979{
7980 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307981 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7983 (hdd_list_node_t*) pAdapterNode,
7984 (hdd_list_node_t**)pNextAdapterNode );
7985
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307986 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 return status;
7988}
7989
7990VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7991 hdd_adapter_list_node_t* pAdapterNode)
7992{
7993 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307994 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7996 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307997 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 return status;
7999}
8000
8001VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
8002 hdd_adapter_list_node_t** ppAdapterNode)
8003{
8004 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308005 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
8007 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308008 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 return status;
8010}
8011
8012VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
8013 hdd_adapter_list_node_t* pAdapterNode)
8014{
8015 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308016 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
8018 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308019 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 return status;
8021}
8022
8023VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
8024 hdd_adapter_list_node_t* pAdapterNode)
8025{
8026 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308027 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8029 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308030 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 return status;
8032}
8033
8034hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8035 tSirMacAddr macAddr )
8036{
8037 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8038 hdd_adapter_t *pAdapter;
8039 VOS_STATUS status;
8040
8041 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8042
8043 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8044 {
8045 pAdapter = pAdapterNode->pAdapter;
8046
8047 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8048 macAddr, sizeof(tSirMacAddr) ) )
8049 {
8050 return pAdapter;
8051 }
8052 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8053 pAdapterNode = pNext;
8054 }
8055
8056 return NULL;
8057
8058}
8059
8060hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8061{
8062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8063 hdd_adapter_t *pAdapter;
8064 VOS_STATUS status;
8065
8066 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8067
8068 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8069 {
8070 pAdapter = pAdapterNode->pAdapter;
8071
8072 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8073 IFNAMSIZ ) )
8074 {
8075 return pAdapter;
8076 }
8077 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8078 pAdapterNode = pNext;
8079 }
8080
8081 return NULL;
8082
8083}
8084
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05308085hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8086 tANI_U32 sme_session_id )
8087{
8088 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8089 hdd_adapter_t *pAdapter;
8090 VOS_STATUS vos_status;
8091
8092
8093 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8094
8095 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8096 {
8097 pAdapter = pAdapterNode->pAdapter;
8098
8099 if (pAdapter->sessionId == sme_session_id)
8100 return pAdapter;
8101
8102 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8103 pAdapterNode = pNext;
8104 }
8105
8106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8107 "%s: sme_session_id %d does not exist with host",
8108 __func__, sme_session_id);
8109
8110 return NULL;
8111}
8112
Jeff Johnson295189b2012-06-20 16:38:30 -07008113hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8114{
8115 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8116 hdd_adapter_t *pAdapter;
8117 VOS_STATUS status;
8118
8119 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8120
8121 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8122 {
8123 pAdapter = pAdapterNode->pAdapter;
8124
8125 if( pAdapter && (mode == pAdapter->device_mode) )
8126 {
8127 return pAdapter;
8128 }
8129 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8130 pAdapterNode = pNext;
8131 }
8132
8133 return NULL;
8134
8135}
8136
8137//Remove this function later
8138hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8139{
8140 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8141 hdd_adapter_t *pAdapter;
8142 VOS_STATUS status;
8143
8144 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8145
8146 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8147 {
8148 pAdapter = pAdapterNode->pAdapter;
8149
8150 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8151 {
8152 return pAdapter;
8153 }
8154
8155 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8156 pAdapterNode = pNext;
8157 }
8158
8159 return NULL;
8160
8161}
8162
Jeff Johnson295189b2012-06-20 16:38:30 -07008163/**---------------------------------------------------------------------------
8164
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308165 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008166
8167 This API returns the operating channel of the requested device mode
8168
8169 \param - pHddCtx - Pointer to the HDD context.
8170 - mode - Device mode for which operating channel is required
8171 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8172 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8173 \return - channel number. "0" id the requested device is not found OR it is not connected.
8174 --------------------------------------------------------------------------*/
8175v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8176{
8177 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8178 VOS_STATUS status;
8179 hdd_adapter_t *pAdapter;
8180 v_U8_t operatingChannel = 0;
8181
8182 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8183
8184 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8185 {
8186 pAdapter = pAdapterNode->pAdapter;
8187
8188 if( mode == pAdapter->device_mode )
8189 {
8190 switch(pAdapter->device_mode)
8191 {
8192 case WLAN_HDD_INFRA_STATION:
8193 case WLAN_HDD_P2P_CLIENT:
8194 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8195 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8196 break;
8197 case WLAN_HDD_SOFTAP:
8198 case WLAN_HDD_P2P_GO:
8199 /*softap connection info */
8200 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8201 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8202 break;
8203 default:
8204 break;
8205 }
8206
8207 break; //Found the device of interest. break the loop
8208 }
8209
8210 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8211 pAdapterNode = pNext;
8212 }
8213 return operatingChannel;
8214}
8215
8216#ifdef WLAN_FEATURE_PACKET_FILTERING
8217/**---------------------------------------------------------------------------
8218
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308219 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008220
8221 This used to set the multicast address list.
8222
8223 \param - dev - Pointer to the WLAN device.
8224 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308225 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008226
8227 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308228static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008229{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308230 hdd_adapter_t *pAdapter;
8231 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308233 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308236 ENTER();
8237
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308238 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308239 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 {
8241 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308242 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 return;
8244 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8246 ret = wlan_hdd_validate_context(pHddCtx);
8247 if (0 != ret)
8248 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308249 return;
8250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 if (dev->flags & IFF_ALLMULTI)
8252 {
8253 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008254 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308255 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308257 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 {
8259 mc_count = netdev_mc_count(dev);
8260 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008261 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8263 {
8264 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008265 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308266 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 return;
8268 }
8269
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308270 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008271
8272 netdev_for_each_mc_addr(ha, dev) {
8273 if (i == mc_count)
8274 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308275 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8276 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308278 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308279 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 i++;
8281 }
8282 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308283
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05308284 if (pHddCtx->hdd_wlan_suspended)
8285 {
8286 /*
8287 * Configure the Mcast address list to FW
8288 * If wlan is already in suspend mode
8289 */
8290 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
8291 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308292 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008293 return;
8294}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308295
8296static void hdd_set_multicast_list(struct net_device *dev)
8297{
8298 vos_ssr_protect(__func__);
8299 __hdd_set_multicast_list(dev);
8300 vos_ssr_unprotect(__func__);
8301}
Jeff Johnson295189b2012-06-20 16:38:30 -07008302#endif
8303
8304/**---------------------------------------------------------------------------
8305
8306 \brief hdd_select_queue() -
8307
8308 This function is registered with the Linux OS for network
8309 core to decide which queue to use first.
8310
8311 \param - dev - Pointer to the WLAN device.
8312 - skb - Pointer to OS packet (sk_buff).
8313 \return - ac, Queue Index/access category corresponding to UP in IP header
8314
8315 --------------------------------------------------------------------------*/
8316v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308317 struct sk_buff *skb
8318#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8319 , void *accel_priv
8320#endif
8321#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8322 , select_queue_fallback_t fallback
8323#endif
8324)
Jeff Johnson295189b2012-06-20 16:38:30 -07008325{
8326 return hdd_wmm_select_queue(dev, skb);
8327}
8328
8329
8330/**---------------------------------------------------------------------------
8331
8332 \brief hdd_wlan_initial_scan() -
8333
8334 This function triggers the initial scan
8335
8336 \param - pAdapter - Pointer to the HDD adapter.
8337
8338 --------------------------------------------------------------------------*/
8339void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8340{
8341 tCsrScanRequest scanReq;
8342 tCsrChannelInfo channelInfo;
8343 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008344 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8346
8347 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8348 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8349 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8350
8351 if(sme_Is11dSupported(pHddCtx->hHal))
8352 {
8353 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8354 if ( HAL_STATUS_SUCCESS( halStatus ) )
8355 {
8356 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8357 if( !scanReq.ChannelInfo.ChannelList )
8358 {
8359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8360 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008361 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 return;
8363 }
8364 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8365 channelInfo.numOfChannels);
8366 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8367 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008368 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 }
8370
8371 scanReq.scanType = eSIR_PASSIVE_SCAN;
8372 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8373 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8374 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8375 }
8376 else
8377 {
8378 scanReq.scanType = eSIR_ACTIVE_SCAN;
8379 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8380 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8381 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8382 }
8383
8384 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8385 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8386 {
8387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8388 __func__, halStatus );
8389 }
8390
8391 if(sme_Is11dSupported(pHddCtx->hHal))
8392 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8393}
8394
mukul sharmabab477d2015-06-11 17:14:55 +05308395void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8396{
8397 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8398 VOS_STATUS status;
8399 hdd_adapter_t *pAdapter;
8400
8401 ENTER();
8402
8403 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8404
8405 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8406 {
8407 pAdapter = pAdapterNode->pAdapter;
8408
8409 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8410 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8411 pAdapterNode = pNext;
8412 }
8413
8414 EXIT();
8415}
Jeff Johnson295189b2012-06-20 16:38:30 -07008416/**---------------------------------------------------------------------------
8417
8418 \brief hdd_full_power_callback() - HDD full power callback function
8419
8420 This is the function invoked by SME to inform the result of a full power
8421 request issued by HDD
8422
8423 \param - callbackcontext - Pointer to cookie
8424 \param - status - result of request
8425
8426 \return - None
8427
8428 --------------------------------------------------------------------------*/
8429static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8430{
Jeff Johnson72a40512013-12-19 10:14:15 -08008431 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008432
8433 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308434 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
8436 if (NULL == callbackContext)
8437 {
8438 hddLog(VOS_TRACE_LEVEL_ERROR,
8439 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008440 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 return;
8442 }
8443
Jeff Johnson72a40512013-12-19 10:14:15 -08008444 /* there is a race condition that exists between this callback
8445 function and the caller since the caller could time out either
8446 before or while this code is executing. we use a spinlock to
8447 serialize these actions */
8448 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008449
8450 if (POWER_CONTEXT_MAGIC != pContext->magic)
8451 {
8452 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008453 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 hddLog(VOS_TRACE_LEVEL_WARN,
8455 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008456 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 return;
8458 }
8459
Jeff Johnson72a40512013-12-19 10:14:15 -08008460 /* context is valid so caller is still waiting */
8461
8462 /* paranoia: invalidate the magic */
8463 pContext->magic = 0;
8464
8465 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008467
8468 /* serialization is complete */
8469 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008470}
8471
Katya Nigamf0511f62015-05-05 16:40:57 +05308472void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8473{
8474 pMonCtx->typeSubtypeBitmap = 0;
8475 if( type%10 ) /* Management Packets */
8476 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8477 type/=10;
8478 if( type%10 ) /* Control Packets */
8479 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8480 type/=10;
8481 if( type%10 ) /* Data Packets */
8482 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8483}
8484
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308485VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8486 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308487{
8488 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308489 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308490
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308491 if (MON_MODE_START == pMonCtx->state)
8492 monMsg.type = WDA_MON_START_REQ;
8493 else if (MON_MODE_STOP == pMonCtx->state)
8494 monMsg.type = WDA_MON_STOP_REQ;
8495 else {
8496 hddLog(VOS_TRACE_LEVEL_ERROR,
8497 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308498 return VOS_STATUS_E_FAILURE;
8499 }
8500
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308501 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8502 if (pMonModeReq == NULL) {
8503 hddLog(VOS_TRACE_LEVEL_ERROR,
8504 FL("fail to allocate memory for monitor mode req"));
8505 return VOS_STATUS_E_FAILURE;
8506 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308507
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308508 pMonModeReq->magic = magic;
8509 pMonModeReq->cmpVar = cmpVar;
8510 pMonModeReq->data = pMonCtx;
8511 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308512
Katya Nigamf0511f62015-05-05 16:40:57 +05308513 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308514 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308515 monMsg.bodyval = 0;
8516
8517 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8518 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8519 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308520 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308521 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308522 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308523}
8524
Katya Nigame7b69a82015-04-28 15:24:06 +05308525void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8526{
8527 VOS_STATUS vosStatus;
8528 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308529 long ret;
8530 hdd_mon_ctx_t *pMonCtx = NULL;
8531 v_U32_t magic;
8532 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308533
Katya Nigame7b69a82015-04-28 15:24:06 +05308534 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8535 if(pAdapter == NULL || pVosContext == NULL)
8536 {
8537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8538 return ;
8539 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308540
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308541 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8542 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8543 pMonCtx->state = MON_MODE_STOP;
8544 magic = MON_MODE_MSG_MAGIC;
8545 init_completion(&cmpVar);
8546 if (VOS_STATUS_SUCCESS !=
8547 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8548 pMonCtx, hdd_monPostMsgCb)) {
8549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8550 FL("failed to post MON MODE REQ"));
8551 pMonCtx->state = MON_MODE_START;
8552 magic = 0;
8553 return;
8554 }
8555 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8556 magic = 0;
8557 if (ret <= 0 ) {
8558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8559 FL("timeout on monitor mode completion %ld"), ret);
8560 }
8561 }
8562
Katya Nigame7b69a82015-04-28 15:24:06 +05308563 hdd_UnregisterWext(pAdapter->dev);
8564
8565 vos_mon_stop( pVosContext );
8566
8567 vosStatus = vos_sched_close( pVosContext );
8568 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8569 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8570 "%s: Failed to close VOSS Scheduler",__func__);
8571 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8572 }
8573
8574 vosStatus = vos_nv_close();
8575 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8576 {
8577 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8578 "%s: Failed to close NV", __func__);
8579 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8580 }
8581
8582 vos_close(pVosContext);
8583
8584 #ifdef WLAN_KD_READY_NOTIFIER
8585 nl_srv_exit(pHddCtx->ptt_pid);
8586 #else
8587 nl_srv_exit();
8588 #endif
8589
Katya Nigame7b69a82015-04-28 15:24:06 +05308590 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308591}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308592/**
8593 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
8594 * @ wiphy: the wiphy to validate against
8595 *
8596 * Return: void
8597 */
8598void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
8599{
8600 int i =0;
8601 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8602 {
8603 if (NULL != wiphy->bands[i] &&
8604 (NULL != wiphy->bands[i]->channels))
8605 {
8606 vos_mem_free(wiphy->bands[i]->channels);
8607 wiphy->bands[i]->channels = NULL;
8608 }
8609 }
8610}
Jeff Johnson295189b2012-06-20 16:38:30 -07008611/**---------------------------------------------------------------------------
8612
8613 \brief hdd_wlan_exit() - HDD WLAN exit function
8614
8615 This is the driver exit point (invoked during rmmod)
8616
8617 \param - pHddCtx - Pointer to the HDD Context
8618
8619 \return - None
8620
8621 --------------------------------------------------------------------------*/
8622void hdd_wlan_exit(hdd_context_t *pHddCtx)
8623{
8624 eHalStatus halStatus;
8625 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8626 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308627 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008628 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008629 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308631 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008632
8633 ENTER();
8634
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308635
Katya Nigame7b69a82015-04-28 15:24:06 +05308636 if (VOS_MONITOR_MODE == hdd_get_conparam())
8637 {
8638 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8639 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308640 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308641 }
8642 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008643 {
8644 // Unloading, restart logic is no more required.
8645 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008646
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308647#ifdef FEATURE_WLAN_TDLS
8648 /* At the time of driver unloading; if tdls connection is present;
8649 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8650 * wlan_hdd_tdls_find_peer always checks for valid context;
8651 * as load/unload in progress there can be a race condition.
8652 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8653 * when tdls state is enabled.
8654 * As soon as driver set load/unload flag; tdls flag also needs
8655 * to be disabled so that hdd_rx_packet_cbk won't call
8656 * wlan_hdd_tdls_find_peer.
8657 */
8658 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8659#endif
8660
c_hpothu5ab05e92014-06-13 17:34:05 +05308661 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8662 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308664 pAdapter = pAdapterNode->pAdapter;
8665 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308667 /* Disable TX on the interface, after this hard_start_xmit() will
8668 * not be called on that interface
8669 */
8670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8671 netif_tx_disable(pAdapter->dev);
8672
8673 /* Mark the interface status as "down" for outside world */
8674 netif_carrier_off(pAdapter->dev);
8675
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308676 /* DeInit the adapter. This ensures that all data packets
8677 * are freed.
8678 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308679#ifdef FEATURE_WLAN_TDLS
8680 mutex_lock(&pHddCtx->tdls_lock);
8681#endif
c_hpothu002231a2015-02-05 14:58:51 +05308682 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308683#ifdef FEATURE_WLAN_TDLS
8684 mutex_unlock(&pHddCtx->tdls_lock);
8685#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308686
c_hpothu5ab05e92014-06-13 17:34:05 +05308687 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8688 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8689 {
8690 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8691 hdd_UnregisterWext(pAdapter->dev);
8692 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308693
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308695 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8696 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 }
mukul sharmabab477d2015-06-11 17:14:55 +05308698
8699 //Purge all sme cmd's for all interface
8700 hdd_purge_cmd_list_all_adapters(pHddCtx);
8701
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308702 // Cancel any outstanding scan requests. We are about to close all
8703 // of our adapters, but an adapter structure is what SME passes back
8704 // to our callback function. Hence if there are any outstanding scan
8705 // requests then there is a race condition between when the adapter
8706 // is closed and when the callback is invoked.We try to resolve that
8707 // race condition here by canceling any outstanding scans before we
8708 // close the adapters.
8709 // Note that the scans may be cancelled in an asynchronous manner,
8710 // so ideally there needs to be some kind of synchronization. Rather
8711 // than introduce a new synchronization here, we will utilize the
8712 // fact that we are about to Request Full Power, and since that is
8713 // synchronized, the expectation is that by the time Request Full
8714 // Power has completed all scans will be cancelled.
8715 if (pHddCtx->scan_info.mScanPending)
8716 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308717 if(NULL != pAdapter)
8718 {
8719 hddLog(VOS_TRACE_LEVEL_INFO,
8720 FL("abort scan mode: %d sessionId: %d"),
8721 pAdapter->device_mode,
8722 pAdapter->sessionId);
8723 }
8724 hdd_abort_mac_scan(pHddCtx,
8725 pHddCtx->scan_info.sessionId,
8726 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308729 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008730 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308731 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308732 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8733 {
8734 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8736 "%s: in middle of FTM START", __func__);
8737 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8738 msecs_to_jiffies(20000));
8739 if(!lrc)
8740 {
8741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8742 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8743 }
8744 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008745 wlan_hdd_ftm_close(pHddCtx);
8746 goto free_hdd_ctx;
8747 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308748
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 /* DeRegister with platform driver as client for Suspend/Resume */
8750 vosStatus = hddDeregisterPmOps(pHddCtx);
8751 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8752 {
8753 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8754 VOS_ASSERT(0);
8755 }
8756
8757 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8758 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8759 {
8760 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008762
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008763 //Stop the traffic monitor timer
8764 if ( VOS_TIMER_STATE_RUNNING ==
8765 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8766 {
8767 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8768 }
8769
8770 // Destroy the traffic monitor timer
8771 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8772 &pHddCtx->tx_rx_trafficTmr)))
8773 {
8774 hddLog(VOS_TRACE_LEVEL_ERROR,
8775 "%s: Cannot deallocate Traffic monitor timer", __func__);
8776 }
8777
Bhargav Shahd0715912015-10-01 18:17:37 +05308778 if (VOS_TIMER_STATE_RUNNING ==
8779 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
8780 vos_timer_stop(&pHddCtx->delack_timer);
8781 }
8782
8783 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8784 &pHddCtx->delack_timer))) {
8785 hddLog(VOS_TRACE_LEVEL_ERROR,
8786 "%s: Cannot deallocate Bus bandwidth timer", __func__);
8787 }
8788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 //Disable IMPS/BMPS as we do not want the device to enter any power
8790 //save mode during shutdown
8791 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8792 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8793 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8794
8795 //Ensure that device is in full power as we will touch H/W during vos_Stop
8796 init_completion(&powerContext.completion);
8797 powerContext.magic = POWER_CONTEXT_MAGIC;
8798
8799 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8800 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8801
8802 if (eHAL_STATUS_SUCCESS != halStatus)
8803 {
8804 if (eHAL_STATUS_PMC_PENDING == halStatus)
8805 {
8806 /* request was sent -- wait for the response */
8807 lrc = wait_for_completion_interruptible_timeout(
8808 &powerContext.completion,
8809 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 if (lrc <= 0)
8811 {
8812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008813 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 }
8815 }
8816 else
8817 {
8818 hddLog(VOS_TRACE_LEVEL_ERROR,
8819 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008820 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 /* continue -- need to clean up as much as possible */
8822 }
8823 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308824 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8825 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8826 {
8827 /* This will issue a dump command which will clean up
8828 BTQM queues and unblock MC thread */
8829 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008831
Jeff Johnson72a40512013-12-19 10:14:15 -08008832 /* either we never sent a request, we sent a request and received a
8833 response or we sent a request and timed out. if we never sent a
8834 request or if we sent a request and got a response, we want to
8835 clear the magic out of paranoia. if we timed out there is a
8836 race condition such that the callback function could be
8837 executing at the same time we are. of primary concern is if the
8838 callback function had already verified the "magic" but had not
8839 yet set the completion variable when a timeout occurred. we
8840 serialize these activities by invalidating the magic while
8841 holding a shared spinlock which will cause us to block if the
8842 callback is currently executing */
8843 spin_lock(&hdd_context_lock);
8844 powerContext.magic = 0;
8845 spin_unlock(&hdd_context_lock);
8846
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308847 /* If Device is shutdown, no point for SME to wait for responses
8848 from device. Pre Close SME */
8849 if(wcnss_device_is_shutdown())
8850 {
8851 sme_PreClose(pHddCtx->hHal);
8852 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008853 hdd_debugfs_exit(pHddCtx);
8854
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308855#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308856 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308857 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8858#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308859 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308860 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8861
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 // Unregister the Net Device Notifier
8863 unregister_netdevice_notifier(&hdd_netdev_notifier);
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 hdd_stop_all_adapters( pHddCtx );
8866
Jeff Johnson295189b2012-06-20 16:38:30 -07008867#ifdef WLAN_BTAMP_FEATURE
8868 vosStatus = WLANBAP_Stop(pVosContext);
8869 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8870 {
8871 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8872 "%s: Failed to stop BAP",__func__);
8873 }
8874#endif //WLAN_BTAMP_FEATURE
8875
8876 //Stop all the modules
8877 vosStatus = vos_stop( pVosContext );
8878 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8879 {
8880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8881 "%s: Failed to stop VOSS",__func__);
8882 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05308883 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 }
8885
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008888
8889 //Close the scheduler before calling vos_close to make sure no thread is
8890 // scheduled after the each module close is called i.e after all the data
8891 // structures are freed.
8892 vosStatus = vos_sched_close( pVosContext );
8893 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8894 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8895 "%s: Failed to close VOSS Scheduler",__func__);
8896 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8897 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008898#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8899 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308900 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008901#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008902 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308903 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008904
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308905#ifdef CONFIG_ENABLE_LINUX_REG
8906 vosStatus = vos_nv_close();
8907 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8908 {
8909 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8910 "%s: Failed to close NV", __func__);
8911 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8912 }
8913#endif
8914
Jeff Johnson295189b2012-06-20 16:38:30 -07008915 //Close VOSS
8916 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8917 vos_close(pVosContext);
8918
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 //Close Watchdog
8920 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8921 vos_watchdog_close(pVosContext);
8922
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308923 //Clean up HDD Nlink Service
8924 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308925
c_manjeecfd1efb2015-09-25 19:32:34 +05308926 wlan_free_fwr_mem_dump_buffer();
8927 memdump_deinit();
8928
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308929#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308930 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308931 {
8932 wlan_logging_sock_deactivate_svc();
8933 }
8934#endif
8935
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308936#ifdef WLAN_KD_READY_NOTIFIER
8937 nl_srv_exit(pHddCtx->ptt_pid);
8938#else
8939 nl_srv_exit();
8940#endif /* WLAN_KD_READY_NOTIFIER */
8941
8942
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 hdd_close_all_adapters( pHddCtx );
8944
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05308945 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
8946
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308947free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 /* free the power on lock from platform driver */
8949 if (free_riva_power_on_lock("wlan"))
8950 {
8951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8952 __func__);
8953 }
8954
c_hpothu78c7b602014-05-17 17:35:49 +05308955 //Free up dynamically allocated members inside HDD Adapter
8956 if (pHddCtx->cfg_ini)
8957 {
8958 kfree(pHddCtx->cfg_ini);
8959 pHddCtx->cfg_ini= NULL;
8960 }
8961
Leo Changf04ddad2013-09-18 13:46:38 -07008962 /* FTM mode, WIPHY did not registered
8963 If un-register here, system crash will happen */
8964 if (VOS_FTM_MODE != hdd_get_conparam())
8965 {
8966 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308967 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -07008968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 if (hdd_is_ssr_required())
8971 {
8972 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008973 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 msleep(5000);
8975 }
8976 hdd_set_ssr_required (VOS_FALSE);
8977}
8978
8979
8980/**---------------------------------------------------------------------------
8981
8982 \brief hdd_update_config_from_nv() - Function to update the contents of
8983 the running configuration with parameters taken from NV storage
8984
8985 \param - pHddCtx - Pointer to the HDD global context
8986
8987 \return - VOS_STATUS_SUCCESS if successful
8988
8989 --------------------------------------------------------------------------*/
8990static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8991{
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 v_BOOL_t itemIsValid = VOS_FALSE;
8993 VOS_STATUS status;
8994 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8995 v_U8_t macLoop;
8996
8997 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8998 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8999 if(status != VOS_STATUS_SUCCESS)
9000 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009001 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07009002 return VOS_STATUS_E_FAILURE;
9003 }
9004
9005 if (itemIsValid == VOS_TRUE)
9006 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009007 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
9009 VOS_MAX_CONCURRENCY_PERSONA);
9010 if(status != VOS_STATUS_SUCCESS)
9011 {
9012 /* Get MAC from NV fail, not update CFG info
9013 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08009014 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 return VOS_STATUS_E_FAILURE;
9016 }
9017
9018 /* If first MAC is not valid, treat all others are not valid
9019 * Then all MACs will be got from ini file */
9020 if(vos_is_macaddr_zero(&macFromNV[0]))
9021 {
9022 /* MAC address in NV file is not configured yet */
9023 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
9024 return VOS_STATUS_E_INVAL;
9025 }
9026
9027 /* Get MAC address from NV, update CFG info */
9028 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
9029 {
9030 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
9031 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309032 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 /* This MAC is not valid, skip it
9034 * This MAC will be got from ini file */
9035 }
9036 else
9037 {
9038 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
9039 (v_U8_t *)&macFromNV[macLoop].bytes[0],
9040 VOS_MAC_ADDR_SIZE);
9041 }
9042 }
9043 }
9044 else
9045 {
9046 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
9047 return VOS_STATUS_E_FAILURE;
9048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009049
Jeff Johnson295189b2012-06-20 16:38:30 -07009050
9051 return VOS_STATUS_SUCCESS;
9052}
9053
9054/**---------------------------------------------------------------------------
9055
9056 \brief hdd_post_voss_start_config() - HDD post voss start config helper
9057
9058 \param - pAdapter - Pointer to the HDD
9059
9060 \return - None
9061
9062 --------------------------------------------------------------------------*/
9063VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
9064{
9065 eHalStatus halStatus;
9066 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309067 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009068
Jeff Johnson295189b2012-06-20 16:38:30 -07009069
9070 // Send ready indication to the HDD. This will kick off the MAC
9071 // into a 'running' state and should kick off an initial scan.
9072 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9073 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9074 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309075 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 "code %08d [x%08x]",__func__, halStatus, halStatus );
9077 return VOS_STATUS_E_FAILURE;
9078 }
9079
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309080 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9082 // And RIVA will crash
9083 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9084 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309085 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9086 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9087
9088
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 return VOS_STATUS_SUCCESS;
9090}
9091
Jeff Johnson295189b2012-06-20 16:38:30 -07009092/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309093void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009094{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309095
9096 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9097
Jeff Johnson295189b2012-06-20 16:38:30 -07009098}
9099
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309100void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009101{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309102
9103 vos_wake_lock_release(&wlan_wake_lock, reason);
9104
Jeff Johnson295189b2012-06-20 16:38:30 -07009105}
9106
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309107void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009108{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309109
9110 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9111 reason);
9112
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009113}
9114
Jeff Johnson295189b2012-06-20 16:38:30 -07009115/**---------------------------------------------------------------------------
9116
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009117 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9118 information between Host and Riva
9119
9120 This function gets reported version of FW
9121 It also finds the version of Riva headers used to compile the host
9122 It compares the above two and prints a warning if they are different
9123 It gets the SW and HW version string
9124 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9125 indicating the features they support through a bitmap
9126
9127 \param - pHddCtx - Pointer to HDD context
9128
9129 \return - void
9130
9131 --------------------------------------------------------------------------*/
9132
9133void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9134{
9135
9136 tSirVersionType versionCompiled;
9137 tSirVersionType versionReported;
9138 tSirVersionString versionString;
9139 tANI_U8 fwFeatCapsMsgSupported = 0;
9140 VOS_STATUS vstatus;
9141
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009142 memset(&versionCompiled, 0, sizeof(versionCompiled));
9143 memset(&versionReported, 0, sizeof(versionReported));
9144
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009145 /* retrieve and display WCNSS version information */
9146 do {
9147
9148 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9149 &versionCompiled);
9150 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9151 {
9152 hddLog(VOS_TRACE_LEVEL_FATAL,
9153 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009154 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009155 break;
9156 }
9157
9158 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9159 &versionReported);
9160 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9161 {
9162 hddLog(VOS_TRACE_LEVEL_FATAL,
9163 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009164 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009165 break;
9166 }
9167
9168 if ((versionCompiled.major != versionReported.major) ||
9169 (versionCompiled.minor != versionReported.minor) ||
9170 (versionCompiled.version != versionReported.version) ||
9171 (versionCompiled.revision != versionReported.revision))
9172 {
9173 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9174 "Host expected %u.%u.%u.%u\n",
9175 WLAN_MODULE_NAME,
9176 (int)versionReported.major,
9177 (int)versionReported.minor,
9178 (int)versionReported.version,
9179 (int)versionReported.revision,
9180 (int)versionCompiled.major,
9181 (int)versionCompiled.minor,
9182 (int)versionCompiled.version,
9183 (int)versionCompiled.revision);
9184 }
9185 else
9186 {
9187 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9188 WLAN_MODULE_NAME,
9189 (int)versionReported.major,
9190 (int)versionReported.minor,
9191 (int)versionReported.version,
9192 (int)versionReported.revision);
9193 }
9194
9195 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9196 versionString,
9197 sizeof(versionString));
9198 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9199 {
9200 hddLog(VOS_TRACE_LEVEL_FATAL,
9201 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009202 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009203 break;
9204 }
9205
9206 pr_info("%s: WCNSS software version %s\n",
9207 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +05309208 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009209
9210 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9211 versionString,
9212 sizeof(versionString));
9213 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9214 {
9215 hddLog(VOS_TRACE_LEVEL_FATAL,
9216 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009217 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009218 break;
9219 }
9220
9221 pr_info("%s: WCNSS hardware version %s\n",
9222 WLAN_MODULE_NAME, versionString);
9223
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009224 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9225 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009226 send the message only if it the riva is 1.1
9227 minor numbers for different riva branches:
9228 0 -> (1.0)Mainline Build
9229 1 -> (1.1)Mainline Build
9230 2->(1.04) Stability Build
9231 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009232 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009233 ((versionReported.minor>=1) && (versionReported.version>=1)))
9234 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9235 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009236
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009237 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009238 {
9239#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9240 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9241 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9242#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009243 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9244 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9245 {
9246 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9247 }
9248
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009249 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009250 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009251
9252 } while (0);
9253
9254}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309255void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9256{
9257 struct sk_buff *skb;
9258 struct nlmsghdr *nlh;
9259 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309260 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +05309261 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309262
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309263 if (in_interrupt() || irqs_disabled() || in_atomic())
9264 flags = GFP_ATOMIC;
9265
9266 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309267
9268 if(skb == NULL) {
9269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9270 "%s: alloc_skb failed", __func__);
9271 return;
9272 }
9273
9274 nlh = (struct nlmsghdr *)skb->data;
9275 nlh->nlmsg_pid = 0; /* from kernel */
9276 nlh->nlmsg_flags = 0;
9277 nlh->nlmsg_seq = 0;
9278 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9279
9280 ani_hdr = NLMSG_DATA(nlh);
9281 ani_hdr->type = type;
9282
9283 switch(type) {
9284 case WLAN_SVC_SAP_RESTART_IND:
9285 ani_hdr->length = 0;
9286 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9287 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9288 break;
Bhargav Shahd0715912015-10-01 18:17:37 +05309289 case WLAN_SVC_WLAN_TP_IND:
9290 ani_hdr->length = len;
9291 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
9292 + len));
9293 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9294 memcpy(nl_data, data, len);
9295 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9296 break;
Bhargav shah23c94942015-10-13 12:48:35 +05309297 case WLAN_MSG_RPS_ENABLE_IND:
9298 ani_hdr->length = len;
9299 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9300 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9301 memcpy(nl_data, data, len);
9302 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9303 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309304 default:
9305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9306 "Attempt to send unknown nlink message %d", type);
9307 kfree_skb(skb);
9308 return;
9309 }
9310
9311 nl_srv_bcast(skb);
9312
9313 return;
9314}
9315
Bhargav Shahd0715912015-10-01 18:17:37 +05309316/**
9317 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
9318 * @pHddCtx: Valid Global HDD context pointer
9319 * @rx_packets: Number of RX packet in perticular time
9320 *
9321 * Based on the RX packet this function calculate next value of tcp delack.
9322 * This function compare rx packet value to high and low threshold limit.
9323 *
9324 * Return: void
9325 */
9326void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
9327{
9328 /* average of rx_packets and prev_rx is taken so that
9329 bus width doesnot fluctuate much */
9330 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
9331 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309332
Bhargav Shahd0715912015-10-01 18:17:37 +05309333 pHddCtx->prev_rx = rx_packets;
9334 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
9335 next_rx_level = TP_IND_HIGH;
9336 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
9337 next_rx_level = TP_IND_LOW;
9338
9339 hdd_set_delack_value(pHddCtx, next_rx_level);
9340}
9341
9342#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
9343
9344/**
9345 * hdd_tcp_delack_compute_function() - get link status
9346 * @priv: Valid Global HDD context pointer
9347 *
9348 * This function find number of RX packet during timer life span.
9349 * It request tcp delack with number of RX packet and re-configure delack timer
9350 * for tcpDelAckComputeInterval timer interval.
9351 *
9352 * Return: void
9353 */
9354void hdd_tcp_delack_compute_function(void *priv)
9355{
9356 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
9357 hdd_adapter_t *pAdapter = NULL;
9358 v_U32_t rx_packets = 0;
9359 hdd_adapter_list_node_t *pAdapterNode = NULL;
9360 VOS_STATUS status = 0;
9361
9362 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
9363 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
9364 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
9365 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
9366 continue;
9367
9368 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
9369 pAdapter->prev_rx_packets);
9370 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
9371 }
9372
9373 hdd_request_tcp_delack(pHddCtx, rx_packets);
9374
9375 vos_timer_start(&pHddCtx->delack_timer,
9376 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
9377}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009378
9379/**---------------------------------------------------------------------------
9380
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309381 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9382
9383 \param - pHddCtx - Pointer to the hdd context
9384
9385 \return - true if hardware supports 5GHz
9386
9387 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309388boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309389{
9390 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9391 * then hardware support 5Ghz.
9392 */
9393 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9394 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309395 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309396 return true;
9397 }
9398 else
9399 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309401 __func__);
9402 return false;
9403 }
9404}
9405
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309406/**---------------------------------------------------------------------------
9407
9408 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9409 generate function
9410
9411 This is generate the random mac address for WLAN interface
9412
9413 \param - pHddCtx - Pointer to HDD context
9414 idx - Start interface index to get auto
9415 generated mac addr.
9416 mac_addr - Mac address
9417
9418 \return - 0 for success, < 0 for failure
9419
9420 --------------------------------------------------------------------------*/
9421
9422static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9423 int idx, v_MACADDR_t mac_addr)
9424{
9425 int i;
9426 unsigned int serialno;
9427 serialno = wcnss_get_serial_number();
9428
9429 if (0 != serialno)
9430 {
9431 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9432 bytes of the serial number that can be used to generate
9433 the other 3 bytes of the MAC address. Mask off all but
9434 the lower 3 bytes (this will also make sure we don't
9435 overflow in the next step) */
9436 serialno &= 0x00FFFFFF;
9437
9438 /* we need a unique address for each session */
9439 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9440
9441 /* autogen other Mac addresses */
9442 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9443 {
9444 /* start with the entire default address */
9445 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9446 /* then replace the lower 3 bytes */
9447 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9448 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9449 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9450
9451 serialno++;
9452 hddLog(VOS_TRACE_LEVEL_ERROR,
9453 "%s: Derived Mac Addr: "
9454 MAC_ADDRESS_STR, __func__,
9455 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9456 }
9457
9458 }
9459 else
9460 {
9461 hddLog(LOGE, FL("Failed to Get Serial NO"));
9462 return -1;
9463 }
9464 return 0;
9465}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309466
Katya Nigame7b69a82015-04-28 15:24:06 +05309467int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9468{
9469 VOS_STATUS status;
9470 v_CONTEXT_t pVosContext= NULL;
9471 hdd_adapter_t *pAdapter= NULL;
9472
9473 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9474
9475 if (NULL == pVosContext)
9476 {
9477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9478 "%s: Trying to open VOSS without a PreOpen", __func__);
9479 VOS_ASSERT(0);
9480 return VOS_STATUS_E_FAILURE;
9481 }
9482
9483 status = vos_nv_open();
9484 if (!VOS_IS_STATUS_SUCCESS(status))
9485 {
9486 /* NV module cannot be initialized */
9487 hddLog( VOS_TRACE_LEVEL_FATAL,
9488 "%s: vos_nv_open failed", __func__);
9489 return VOS_STATUS_E_FAILURE;
9490 }
9491
9492 status = vos_init_wiphy_from_nv_bin();
9493 if (!VOS_IS_STATUS_SUCCESS(status))
9494 {
9495 /* NV module cannot be initialized */
9496 hddLog( VOS_TRACE_LEVEL_FATAL,
9497 "%s: vos_init_wiphy failed", __func__);
9498 goto err_vos_nv_close;
9499 }
9500
9501 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9502 if ( !VOS_IS_STATUS_SUCCESS( status ))
9503 {
9504 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9505 goto err_vos_nv_close;
9506 }
9507
9508 status = vos_mon_start( pVosContext );
9509 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9510 {
9511 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9512 goto err_vosclose;
9513 }
9514
9515 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9516 WDA_featureCapsExchange(pVosContext);
9517 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9518
9519 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9520 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9521 if( pAdapter == NULL )
9522 {
9523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9524 goto err_close_adapter;
9525 }
9526
9527 //Initialize the nlink service
9528 if(nl_srv_init() != 0)
9529 {
9530 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9531 goto err_close_adapter;
9532 }
9533 return VOS_STATUS_SUCCESS;
9534
9535err_close_adapter:
9536 hdd_close_all_adapters( pHddCtx );
9537 vos_mon_stop( pVosContext );
9538err_vosclose:
9539 status = vos_sched_close( pVosContext );
9540 if (!VOS_IS_STATUS_SUCCESS(status)) {
9541 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9542 "%s: Failed to close VOSS Scheduler", __func__);
9543 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9544 }
9545 vos_close(pVosContext );
9546
9547err_vos_nv_close:
9548 vos_nv_close();
9549
9550return status;
9551}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309552/**---------------------------------------------------------------------------
9553
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309554 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9555 completed to flush out the scan results
9556
9557 11d scan is done during driver load and is a passive scan on all
9558 channels supported by the device, 11d scans may find some APs on
9559 frequencies which are forbidden to be used in the regulatory domain
9560 the device is operating in. If these APs are notified to the supplicant
9561 it may try to connect to these APs, thus flush out all the scan results
9562 which are present in SME after 11d scan is done.
9563
9564 \return - eHalStatus
9565
9566 --------------------------------------------------------------------------*/
9567static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9568 tANI_U32 scanId, eCsrScanStatus status)
9569{
9570 ENTER();
9571
9572 sme_ScanFlushResult(halHandle, 0);
9573
9574 EXIT();
9575
9576 return eHAL_STATUS_SUCCESS;
9577}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309578/**---------------------------------------------------------------------------
9579
9580 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9581 logging is completed successfully.
9582
9583 \return - None
9584
9585 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +05309586void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309587{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309588 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309589
9590 if (NULL == pHddCtx)
9591 {
9592 hddLog(VOS_TRACE_LEVEL_ERROR,
9593 "%s: HDD context is NULL",__func__);
9594 return;
9595 }
9596
c_manjeecfd1efb2015-09-25 19:32:34 +05309597 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309598 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309599 {
9600 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9601 pHddCtx->mgmt_frame_logging = TRUE;
9602 }
9603 else
9604 {
9605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9606 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +05309607 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309608 }
9609
c_manjeecfd1efb2015-09-25 19:32:34 +05309610 /*Check feature supported by FW*/
9611 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
9612 {
9613 //Store fwr mem dump size given by firmware.
9614 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
9615 }
9616 else
9617 {
9618 wlan_store_fwr_mem_dump_size(0);
9619 }
9620
9621
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309622}
9623/**---------------------------------------------------------------------------
9624
9625 \brief hdd_init_frame_logging - function to initialize frame logging.
9626 Currently only Mgmt Frames are logged in both TX
9627 and Rx direction and are sent to userspace
9628 application using logger thread when queried.
9629
9630 \return - None
9631
9632 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309633void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309634{
9635 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309636 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309637
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309638 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9639 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309640 {
9641 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9642 return;
9643 }
9644
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309645 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9646 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309647 {
9648 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9649 return;
9650 }
9651
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309652 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309653
c_manjeecfd1efb2015-09-25 19:32:34 +05309654 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309655 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9656 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +05309657 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
9658 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309659
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309660 if (pHddCtx->cfg_ini->enableFWLogging ||
9661 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309662 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309663 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309664 }
9665
Sushant Kaushik46804902015-07-08 14:46:03 +05309666 if (pHddCtx->cfg_ini->enableMgmtLogging)
9667 {
9668 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9669 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309670 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9671 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309672 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309673 }
c_manjeecfd1efb2015-09-25 19:32:34 +05309674 if(pHddCtx->cfg_ini->enableFwrMemDump &&
9675 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
9676 {
9677 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
9678 }
9679 if( wlanFWLoggingInitParam->enableFlag == 0 )
9680 {
9681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
9682 return;
9683 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309684 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9685 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9686 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9687 wlanFWLoggingInitParam->continuousFrameLogging =
9688 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309689
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309690 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309691
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309692 wlanFWLoggingInitParam->minLogBufferSize =
9693 pHddCtx->cfg_ini->minLoggingBufferSize;
9694 wlanFWLoggingInitParam->maxLogBufferSize =
9695 pHddCtx->cfg_ini->maxLoggingBufferSize;
9696 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9697 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309698
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309699 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309700
9701 if (eHAL_STATUS_SUCCESS != halStatus)
9702 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309703 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309704 }
9705
9706 return;
9707}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309708
Bhargav shah23c94942015-10-13 12:48:35 +05309709static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
9710{
9711 hdd_adapter_t *adapter;
9712 hdd_adapter_list_node_t *adapter_node, *next;
9713 VOS_STATUS status = VOS_STATUS_SUCCESS;
9714 struct wlan_rps_data rps_data;
9715 int count;
9716
9717 if(!hdd_ctxt->cfg_ini->rps_mask)
9718 {
9719 return;
9720 }
9721
9722 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
9723 {
9724 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
9725 }
9726
9727 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
9728
9729 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
9730 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
9731 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
9732
9733 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
9734
9735 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
9736 {
9737 adapter = adapter_node->pAdapter;
9738 if (NULL != adapter) {
9739 strlcpy(rps_data.ifname, adapter->dev->name,
9740 sizeof(rps_data.ifname));
9741 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
9742 (void *)&rps_data,sizeof(rps_data));
9743 }
9744 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
9745 adapter_node = next;
9746 }
9747}
9748
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309749/**---------------------------------------------------------------------------
9750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 \brief hdd_wlan_startup() - HDD init function
9752
9753 This is the driver startup code executed once a WLAN device has been detected
9754
9755 \param - dev - Pointer to the underlying device
9756
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009757 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009758
9759 --------------------------------------------------------------------------*/
9760
9761int hdd_wlan_startup(struct device *dev )
9762{
9763 VOS_STATUS status;
9764 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009765 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 hdd_context_t *pHddCtx = NULL;
9767 v_CONTEXT_t pVosContext= NULL;
9768#ifdef WLAN_BTAMP_FEATURE
9769 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9770 WLANBAP_ConfigType btAmpConfig;
9771 hdd_config_t *pConfig;
9772#endif
9773 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309775 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009776
9777 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 /*
9779 * cfg80211: wiphy allocation
9780 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309781 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009782
9783 if(wiphy == NULL)
9784 {
9785 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009786 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 pHddCtx = wiphy_priv(wiphy);
9789
Jeff Johnson295189b2012-06-20 16:38:30 -07009790 //Initialize the adapter context to zeros.
9791 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9792
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309794 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309795 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009796
9797 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05309798 pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime();
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309800 /* register for riva power on lock to platform driver
9801 * Locking power early to ensure FW doesn't reset by kernel while
9802 * host driver is busy initializing itself */
9803 if (req_riva_power_on_lock("wlan"))
9804 {
9805 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9806 __func__);
9807 goto err_free_hdd_context;
9808 }
9809
Jeff Johnson295189b2012-06-20 16:38:30 -07009810 /*Get vos context here bcoz vos_open requires it*/
9811 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9812
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009813 if(pVosContext == NULL)
9814 {
9815 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9816 goto err_free_hdd_context;
9817 }
9818
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 //Save the Global VOSS context in adapter context for future.
9820 pHddCtx->pvosContext = pVosContext;
9821
9822 //Save the adapter context in global context for future.
9823 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9824
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 pHddCtx->parent_dev = dev;
9826
9827 init_completion(&pHddCtx->full_pwr_comp_var);
9828 init_completion(&pHddCtx->standby_comp_var);
9829 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009830 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009831 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309832 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309833 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309834 init_completion(&pHddCtx->mc_sus_event_var);
9835 init_completion(&pHddCtx->tx_sus_event_var);
9836 init_completion(&pHddCtx->rx_sus_event_var);
9837
Amar Singhala49cbc52013-10-08 18:37:44 -07009838
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309839 hdd_init_ll_stats_ctx(pHddCtx);
9840
Amar Singhala49cbc52013-10-08 18:37:44 -07009841#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009842 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009843#else
9844 init_completion(&pHddCtx->driver_crda_req);
9845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009846
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05309847#ifdef WLAN_FEATURE_EXTSCAN
9848 init_completion(&pHddCtx->ext_scan_context.response_event);
9849#endif /* WLAN_FEATURE_EXTSCAN */
9850
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309851 spin_lock_init(&pHddCtx->schedScan_lock);
9852
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9854
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05309855 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
9856 hdd_processSpoofMacAddrRequest);
9857
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309858#ifdef FEATURE_WLAN_TDLS
9859 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9860 * invoked by other instances also) to protect the concurrent
9861 * access for the Adapters by TDLS module.
9862 */
9863 mutex_init(&pHddCtx->tdls_lock);
9864#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309865 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309866 mutex_init(&pHddCtx->wmmLock);
9867
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05309868 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +05309869 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309870
Agarwal Ashish1f422872014-07-22 00:11:55 +05309871 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 // Load all config first as TL config is needed during vos_open
9873 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9874 if(pHddCtx->cfg_ini == NULL)
9875 {
9876 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9877 goto err_free_hdd_context;
9878 }
9879
9880 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9881
9882 // Read and parse the qcom_cfg.ini file
9883 status = hdd_parse_config_ini( pHddCtx );
9884 if ( VOS_STATUS_SUCCESS != status )
9885 {
9886 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9887 __func__, WLAN_INI_FILE);
9888 goto err_config;
9889 }
Arif Hussaind5218912013-12-05 01:10:55 -08009890#ifdef MEMORY_DEBUG
9891 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9892 vos_mem_init();
9893
9894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9895 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9896#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009897
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309898 /* INI has been read, initialise the configuredMcastBcastFilter with
9899 * INI value as this will serve as the default value
9900 */
9901 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9902 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9903 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309904
9905 if (false == hdd_is_5g_supported(pHddCtx))
9906 {
9907 //5Ghz is not supported.
9908 if (1 != pHddCtx->cfg_ini->nBandCapability)
9909 {
9910 hddLog(VOS_TRACE_LEVEL_INFO,
9911 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9912 pHddCtx->cfg_ini->nBandCapability = 1;
9913 }
9914 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309915
9916 /* If SNR Monitoring is enabled, FW has to parse all beacons
9917 * for calcaluting and storing the average SNR, so set Nth beacon
9918 * filter to 1 to enable FW to parse all the beaocons
9919 */
9920 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9921 {
9922 /* The log level is deliberately set to WARN as overriding
9923 * nthBeaconFilter to 1 will increase power cosumption and this
9924 * might just prove helpful to detect the power issue.
9925 */
9926 hddLog(VOS_TRACE_LEVEL_WARN,
9927 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9928 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309931 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009933 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009935 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9936 {
9937 hddLog(VOS_TRACE_LEVEL_FATAL,
9938 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9939 goto err_config;
9940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009942
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009943 // Update VOS trace levels based upon the cfg.ini
9944 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9945 pHddCtx->cfg_ini->vosTraceEnableBAP);
9946 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9947 pHddCtx->cfg_ini->vosTraceEnableTL);
9948 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9949 pHddCtx->cfg_ini->vosTraceEnableWDI);
9950 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9951 pHddCtx->cfg_ini->vosTraceEnableHDD);
9952 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9953 pHddCtx->cfg_ini->vosTraceEnableSME);
9954 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9955 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309956 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9957 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009958 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9959 pHddCtx->cfg_ini->vosTraceEnableWDA);
9960 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9961 pHddCtx->cfg_ini->vosTraceEnableSYS);
9962 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9963 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009964 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9965 pHddCtx->cfg_ini->vosTraceEnableSAP);
9966 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9967 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009968
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 // Update WDI trace levels based upon the cfg.ini
9970 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9971 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9972 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9973 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9974 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9975 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9976 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9977 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
Jeff Johnson88ba7742013-02-27 14:36:02 -08009979 if (VOS_FTM_MODE == hdd_get_conparam())
9980 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9982 {
9983 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9984 goto err_free_hdd_context;
9985 }
9986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309987 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309988 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009991
Katya Nigame7b69a82015-04-28 15:24:06 +05309992 if( VOS_MONITOR_MODE == hdd_get_conparam())
9993 {
9994 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9995 {
9996 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9997 goto err_free_hdd_context;
9998 }
9999 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
10000 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
10001 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
10002 return VOS_STATUS_SUCCESS;
10003 }
10004
Jeff Johnson88ba7742013-02-27 14:36:02 -080010005 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10007 {
10008 status = vos_watchdog_open(pVosContext,
10009 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
10010
10011 if(!VOS_IS_STATUS_SUCCESS( status ))
10012 {
10013 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010014 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 }
10016 }
10017
10018 pHddCtx->isLogpInProgress = FALSE;
10019 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
10020
Amar Singhala49cbc52013-10-08 18:37:44 -070010021#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010022 /* initialize the NV module. This is required so that
10023 we can initialize the channel information in wiphy
10024 from the NV.bin data. The channel information in
10025 wiphy needs to be initialized before wiphy registration */
10026
10027 status = vos_nv_open();
10028 if (!VOS_IS_STATUS_SUCCESS(status))
10029 {
10030 /* NV module cannot be initialized */
10031 hddLog( VOS_TRACE_LEVEL_FATAL,
10032 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053010033 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070010034 }
10035
10036 status = vos_init_wiphy_from_nv_bin();
10037 if (!VOS_IS_STATUS_SUCCESS(status))
10038 {
10039 /* NV module cannot be initialized */
10040 hddLog( VOS_TRACE_LEVEL_FATAL,
10041 "%s: vos_init_wiphy failed", __func__);
10042 goto err_vos_nv_close;
10043 }
10044
Amar Singhala49cbc52013-10-08 18:37:44 -070010045#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053010046 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053010047 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 if ( !VOS_IS_STATUS_SUCCESS( status ))
10049 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010050 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +053010051 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 }
10053
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
10055
10056 if ( NULL == pHddCtx->hHal )
10057 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010058 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 goto err_vosclose;
10060 }
10061
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010062 status = vos_preStart( pHddCtx->pvosContext );
10063 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10064 {
10065 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010066 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010067 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010068
Arif Hussaineaf68602013-12-30 23:10:44 -080010069 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
10070 {
10071 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
10072 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
10073 __func__, enable_dfs_chan_scan);
10074 }
10075 if (0 == enable_11d || 1 == enable_11d)
10076 {
10077 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
10078 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
10079 __func__, enable_11d);
10080 }
10081
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010082 /* Note that the vos_preStart() sequence triggers the cfg download.
10083 The cfg download must occur before we update the SME config
10084 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 status = hdd_set_sme_config( pHddCtx );
10086
10087 if ( VOS_STATUS_SUCCESS != status )
10088 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010089 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010090 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010092
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 /* In the integrated architecture we update the configuration from
10094 the INI file and from NV before vOSS has been started so that
10095 the final contents are available to send down to the cCPU */
10096
10097 // Apply the cfg.ini to cfg.dat
10098 if (FALSE == hdd_update_config_dat(pHddCtx))
10099 {
10100 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010101 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 }
10103
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010104 // Get mac addr from platform driver
10105 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
10106
10107 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010109 /* Store the mac addr for first interface */
10110 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
10111
10112 hddLog(VOS_TRACE_LEVEL_ERROR,
10113 "%s: WLAN Mac Addr: "
10114 MAC_ADDRESS_STR, __func__,
10115 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10116
10117 /* Here, passing Arg2 as 1 because we do not want to change the
10118 last 3 bytes (means non OUI bytes) of first interface mac
10119 addr.
10120 */
10121 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
10122 {
10123 hddLog(VOS_TRACE_LEVEL_ERROR,
10124 "%s: Failed to generate wlan interface mac addr "
10125 "using MAC from ini file ", __func__);
10126 }
10127 }
10128 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
10129 {
10130 // Apply the NV to cfg.dat
10131 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070010132#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
10133 /* There was not a valid set of MAC Addresses in NV. See if the
10134 default addresses were modified by the cfg.ini settings. If so,
10135 we'll use them, but if not, we'll autogenerate a set of MAC
10136 addresses based upon the device serial number */
10137
10138 static const v_MACADDR_t default_address =
10139 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070010140
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010141 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
10142 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 {
10144 /* cfg.ini has the default address, invoke autogen logic */
10145
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010146 /* Here, passing Arg2 as 0 because we want to change the
10147 last 3 bytes (means non OUI bytes) of all the interfaces
10148 mac addr.
10149 */
10150 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
10151 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010153 hddLog(VOS_TRACE_LEVEL_ERROR,
10154 "%s: Failed to generate wlan interface mac addr "
10155 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
10156 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 }
10159 else
10160#endif //WLAN_AUTOGEN_MACADDR_FEATURE
10161 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010162 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 "%s: Invalid MAC address in NV, using MAC from ini file "
10164 MAC_ADDRESS_STR, __func__,
10165 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10166 }
10167 }
10168 {
10169 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010170
10171 /* Set the MAC Address Currently this is used by HAL to
10172 * add self sta. Remove this once self sta is added as
10173 * part of session open.
10174 */
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
10176 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
10177 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010178
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 if (!HAL_STATUS_SUCCESS( halStatus ))
10180 {
10181 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
10182 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010183 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 }
10185 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010186
10187 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
10188 Note: Firmware image will be read and downloaded inside vos_start API */
10189 status = vos_start( pHddCtx->pvosContext );
10190 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10191 {
10192 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +053010193 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010194 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 }
10196
Leo Chang6cec3e22014-01-21 15:33:49 -080010197#ifdef FEATURE_WLAN_CH_AVOID
10198 /* Plug in avoid channel notification callback
10199 * This should happen before ADD_SELF_STA
10200 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010201
10202 /* check the Channel Avoidance is enabled */
10203 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10204 {
10205 sme_AddChAvoidCallback(pHddCtx->hHal,
10206 hdd_hostapd_ch_avoid_cb);
10207 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010208#endif /* FEATURE_WLAN_CH_AVOID */
10209
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010210 /* Exchange capability info between Host and FW and also get versioning info from FW */
10211 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010212
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010213#ifdef CONFIG_ENABLE_LINUX_REG
10214 status = wlan_hdd_init_channels(pHddCtx);
10215 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10216 {
10217 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10218 __func__);
10219 goto err_vosstop;
10220 }
10221#endif
10222
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 status = hdd_post_voss_start_config( pHddCtx );
10224 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10225 {
10226 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10227 __func__);
10228 goto err_vosstop;
10229 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010230
10231#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010232 wlan_hdd_cfg80211_update_reg_info( wiphy );
10233
10234 /* registration of wiphy dev with cfg80211 */
10235 if (0 > wlan_hdd_cfg80211_register(wiphy))
10236 {
10237 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10238 goto err_vosstop;
10239 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010240#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010241
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010242#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010243 /* registration of wiphy dev with cfg80211 */
10244 if (0 > wlan_hdd_cfg80211_register(wiphy))
10245 {
10246 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10247 goto err_vosstop;
10248 }
10249
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010250 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010251 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10252 {
10253 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10254 __func__);
10255 goto err_unregister_wiphy;
10256 }
10257#endif
10258
c_hpothu4a298be2014-12-22 21:12:51 +053010259 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10260
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10262 {
10263 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10264 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10265 }
10266 else
10267 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10269 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10270 if (pAdapter != NULL)
10271 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010272 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010273 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010274 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10275 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10276 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010277
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010278 /* Generate the P2P Device Address. This consists of the device's
10279 * primary MAC address with the locally administered bit set.
10280 */
10281 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010282 }
10283 else
10284 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010285 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10286 if (p2p_dev_addr != NULL)
10287 {
10288 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10289 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10290 }
10291 else
10292 {
10293 hddLog(VOS_TRACE_LEVEL_FATAL,
10294 "%s: Failed to allocate mac_address for p2p_device",
10295 __func__);
10296 goto err_close_adapter;
10297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010299
10300 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10301 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10302 if ( NULL == pP2pAdapter )
10303 {
10304 hddLog(VOS_TRACE_LEVEL_FATAL,
10305 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010306 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010307 goto err_close_adapter;
10308 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010311
10312 if( pAdapter == NULL )
10313 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10315 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010317
Arif Hussain66559122013-11-21 10:11:40 -080010318 if (country_code)
10319 {
10320 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010321 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010322 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10323#ifndef CONFIG_ENABLE_LINUX_REG
10324 hdd_checkandupdate_phymode(pAdapter, country_code);
10325#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010326 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10327 (void *)(tSmeChangeCountryCallback)
10328 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010329 country_code,
10330 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010331 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010332 if (eHAL_STATUS_SUCCESS == ret)
10333 {
Arif Hussaincb607082013-12-20 11:57:42 -080010334 ret = wait_for_completion_interruptible_timeout(
10335 &pAdapter->change_country_code,
10336 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10337
10338 if (0 >= ret)
10339 {
10340 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10341 "%s: SME while setting country code timed out", __func__);
10342 }
Arif Hussain66559122013-11-21 10:11:40 -080010343 }
10344 else
10345 {
Arif Hussaincb607082013-12-20 11:57:42 -080010346 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10347 "%s: SME Change Country code from module param fail ret=%d",
10348 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010349 }
10350 }
10351
Jeff Johnson295189b2012-06-20 16:38:30 -070010352#ifdef WLAN_BTAMP_FEATURE
10353 vStatus = WLANBAP_Open(pVosContext);
10354 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10355 {
10356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10357 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010358 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 }
10360
10361 vStatus = BSL_Init(pVosContext);
10362 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10363 {
10364 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10365 "%s: Failed to Init BSL",__func__);
10366 goto err_bap_close;
10367 }
10368 vStatus = WLANBAP_Start(pVosContext);
10369 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10370 {
10371 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10372 "%s: Failed to start TL",__func__);
10373 goto err_bap_close;
10374 }
10375
10376 pConfig = pHddCtx->cfg_ini;
10377 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10378 status = WLANBAP_SetConfig(&btAmpConfig);
10379
10380#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010381
Mihir Shete9c238772014-10-15 14:35:16 +053010382 /*
10383 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10384 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10385 * which is greater than 0xf. So the below check is safe to make
10386 * sure that there is no entry for UapsdMask in the ini
10387 */
10388 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10389 {
10390 if(IS_DYNAMIC_WMM_PS_ENABLED)
10391 {
10392 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10393 __func__);
10394 pHddCtx->cfg_ini->UapsdMask =
10395 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10396 }
10397 else
10398 {
10399 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10400 __func__);
10401 pHddCtx->cfg_ini->UapsdMask =
10402 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10403 }
10404 }
10405
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010406#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10407 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10408 {
10409 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10410 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10411 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10412 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10413 }
10414#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010415
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010416 wlan_hdd_tdls_init(pHddCtx);
10417
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010418 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10419
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 /* Register with platform driver as client for Suspend/Resume */
10421 status = hddRegisterPmOps(pHddCtx);
10422 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10423 {
10424 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10425#ifdef WLAN_BTAMP_FEATURE
10426 goto err_bap_stop;
10427#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010428 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010429#endif //WLAN_BTAMP_FEATURE
10430 }
10431
Yue Ma0d4891e2013-08-06 17:01:45 -070010432 /* Open debugfs interface */
10433 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10434 {
10435 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10436 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010437 }
10438
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 /* Register TM level change handler function to the platform */
10440 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10441 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10442 {
10443 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10444 goto err_unregister_pmops;
10445 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 // register net device notifier for device change notification
10448 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10449
10450 if(ret < 0)
10451 {
10452 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010453 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 }
10455
10456 //Initialize the nlink service
10457 if(nl_srv_init() != 0)
10458 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010459 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 goto err_reg_netdev;
10461 }
10462
Leo Chang4ce1cc52013-10-21 18:27:15 -070010463#ifdef WLAN_KD_READY_NOTIFIER
10464 pHddCtx->kd_nl_init = 1;
10465#endif /* WLAN_KD_READY_NOTIFIER */
10466
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 //Initialize the BTC service
10468 if(btc_activate_service(pHddCtx) != 0)
10469 {
10470 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10471 goto err_nl_srv;
10472 }
10473
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053010474#ifdef FEATURE_OEM_DATA_SUPPORT
10475 //Initialize the OEM service
10476 if (oem_activate_service(pHddCtx) != 0)
10477 {
10478 hddLog(VOS_TRACE_LEVEL_FATAL,
10479 "%s: oem_activate_service failed", __func__);
10480 goto err_nl_srv;
10481 }
10482#endif
10483
Jeff Johnson295189b2012-06-20 16:38:30 -070010484#ifdef PTT_SOCK_SVC_ENABLE
10485 //Initialize the PTT service
10486 if(ptt_sock_activate_svc(pHddCtx) != 0)
10487 {
10488 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10489 goto err_nl_srv;
10490 }
10491#endif
10492
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010493#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10494 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10495 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010496 if(wlan_logging_sock_activate_svc(
10497 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053010498 pHddCtx->cfg_ini->wlanLoggingNumBuf,
10499 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
10500 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053010501 {
10502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10503 " failed", __func__);
10504 goto err_nl_srv;
10505 }
10506 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10507 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010508 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10509 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053010510 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
10511 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010512 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010513
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010514 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10515 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010516 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053010517 pHddCtx->cfg_ini->enableContFWLogging ||
10518 pHddCtx->cfg_ini->enableFwrMemDump )
10519 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010520 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010521 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010522 }
10523 else
10524 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010525 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010526 }
10527
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010528#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010529
10530
Sushant Kaushik215778f2015-05-21 14:05:36 +053010531 if (vos_is_multicast_logging())
10532 wlan_logging_set_log_level();
10533
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010537 /* Action frame registered in one adapter which will
10538 * applicable to all interfaces
10539 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010540 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010542
10543 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010544 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545
Jeff Johnsone7245742012-09-05 17:12:55 -070010546#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10547 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010548 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010549 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010550
Jeff Johnsone7245742012-09-05 17:12:55 -070010551#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010552 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010553 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010554 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010555
Jeff Johnsone7245742012-09-05 17:12:55 -070010556
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010557 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10558 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010559
Katya Nigam5c306ea2014-06-19 15:39:54 +053010560 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010562 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010563
10564#ifdef FEATURE_WLAN_SCAN_PNO
10565 /*SME must send channel update configuration to RIVA*/
10566 sme_UpdateChannelConfig(pHddCtx->hHal);
10567#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010568 /* Send the update default channel list to the FW*/
10569 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010570
10571 /* Fwr capabilities received, Set the Dot11 mode */
10572 sme_SetDefDot11Mode(pHddCtx->hHal);
10573
Abhishek Singha306a442013-11-07 18:39:01 +053010574#ifndef CONFIG_ENABLE_LINUX_REG
10575 /*updating wiphy so that regulatory user hints can be processed*/
10576 if (wiphy)
10577 {
10578 regulatory_hint(wiphy, "00");
10579 }
10580#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010581 // Initialize the restart logic
10582 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010583
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010584 //Register the traffic monitor timer now
10585 if ( pHddCtx->cfg_ini->dynSplitscan)
10586 {
10587 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10588 VOS_TIMER_TYPE_SW,
10589 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10590 (void *)pHddCtx);
10591 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010592 wlan_hdd_cfg80211_nan_init(pHddCtx);
10593
Bhargav Shahd0715912015-10-01 18:17:37 +053010594 mutex_init(&pHddCtx->cur_rx_level_lock);
10595 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
10596 hdd_tcp_delack_compute_function,(void *)pHddCtx);
10597
Dino Mycle6fb96c12014-06-10 11:52:40 +053010598#ifdef WLAN_FEATURE_EXTSCAN
10599 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10600 wlan_hdd_cfg80211_extscan_callback,
10601 pHddCtx);
10602#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010603
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053010604#ifdef FEATURE_OEM_DATA_SUPPORT
10605 sme_OemDataRegisterCallback(pHddCtx->hHal,
10606 wlan_hdd_cfg80211_oemdata_callback,
10607 pHddCtx);
10608#endif /* FEATURE_OEM_DATA_SUPPORT */
10609
Gupta, Kapil7c34b322015-09-30 13:12:35 +053010610 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010611#ifdef WLAN_NS_OFFLOAD
10612 // Register IPv6 notifier to notify if any change in IP
10613 // So that we can reconfigure the offload parameters
10614 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10615 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10616 if (ret)
10617 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010619 }
10620 else
10621 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010622 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010623 }
10624#endif
10625
10626 // Register IPv4 notifier to notify if any change in IP
10627 // So that we can reconfigure the offload parameters
10628 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10629 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10630 if (ret)
10631 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010633 }
10634 else
10635 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010637 }
c_manjeecfd1efb2015-09-25 19:32:34 +053010638 /*Fw mem dump procfs initialization*/
10639 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053010640 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010641
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 goto success;
10643
10644err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010645#ifdef WLAN_KD_READY_NOTIFIER
10646 nl_srv_exit(pHddCtx->ptt_pid);
10647#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010649#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010650err_reg_netdev:
10651 unregister_netdevice_notifier(&hdd_netdev_notifier);
10652
Jeff Johnson295189b2012-06-20 16:38:30 -070010653err_unregister_pmops:
10654 hddDevTmUnregisterNotifyCallback(pHddCtx);
10655 hddDeregisterPmOps(pHddCtx);
10656
Yue Ma0d4891e2013-08-06 17:01:45 -070010657 hdd_debugfs_exit(pHddCtx);
10658
Jeff Johnson295189b2012-06-20 16:38:30 -070010659#ifdef WLAN_BTAMP_FEATURE
10660err_bap_stop:
10661 WLANBAP_Stop(pVosContext);
10662#endif
10663
10664#ifdef WLAN_BTAMP_FEATURE
10665err_bap_close:
10666 WLANBAP_Close(pVosContext);
10667#endif
10668
Jeff Johnson295189b2012-06-20 16:38:30 -070010669err_close_adapter:
10670 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010671#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010672err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010673#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010674 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010675 hdd_wlan_free_wiphy_channels(wiphy);
10676
Jeff Johnson295189b2012-06-20 16:38:30 -070010677err_vosstop:
10678 vos_stop(pVosContext);
10679
Amar Singhala49cbc52013-10-08 18:37:44 -070010680err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 status = vos_sched_close( pVosContext );
10682 if (!VOS_IS_STATUS_SUCCESS(status)) {
10683 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10684 "%s: Failed to close VOSS Scheduler", __func__);
10685 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10686 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010687 vos_close(pVosContext );
10688
Amar Singhal0a402232013-10-11 20:57:16 -070010689err_vos_nv_close:
10690
c_hpothue6a36282014-03-19 12:27:38 +053010691#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010692 vos_nv_close();
10693
c_hpothu70f8d812014-03-22 22:59:23 +053010694#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010695
10696err_wdclose:
10697 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10698 vos_watchdog_close(pVosContext);
10699
Jeff Johnson295189b2012-06-20 16:38:30 -070010700err_config:
10701 kfree(pHddCtx->cfg_ini);
10702 pHddCtx->cfg_ini= NULL;
10703
10704err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010705 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010706 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 wiphy_free(wiphy) ;
10708 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 VOS_BUG(1);
10710
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010711 if (hdd_is_ssr_required())
10712 {
10713 /* WDI timeout had happened during load, so SSR is needed here */
10714 subsystem_restart("wcnss");
10715 msleep(5000);
10716 }
10717 hdd_set_ssr_required (VOS_FALSE);
10718
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010719 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010720
10721success:
10722 EXIT();
10723 return 0;
10724}
10725
10726/**---------------------------------------------------------------------------
10727
Jeff Johnson32d95a32012-09-10 13:15:23 -070010728 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010729
Jeff Johnson32d95a32012-09-10 13:15:23 -070010730 This is the driver entry point - called in different timeline depending
10731 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010732
10733 \param - None
10734
10735 \return - 0 for success, non zero for failure
10736
10737 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010738static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010739{
10740 VOS_STATUS status;
10741 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 struct device *dev = NULL;
10743 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010744#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10745 int max_retries = 0;
10746#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010747#ifdef HAVE_CBC_DONE
10748 int max_cbc_retries = 0;
10749#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010750
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010751#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10752 wlan_logging_sock_init_svc();
10753#endif
10754
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 ENTER();
10756
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010757 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010758
10759 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10760 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10761
Jeff Johnson295189b2012-06-20 16:38:30 -070010762#ifdef ANI_BUS_TYPE_PCI
10763
10764 dev = wcnss_wlan_get_device();
10765
10766#endif // ANI_BUS_TYPE_PCI
10767
10768#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010769
10770#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10771 /* wait until WCNSS driver downloads NV */
10772 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10773 msleep(1000);
10774 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010775
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010776 if (max_retries >= 5) {
10777 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010778 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010779#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10780 wlan_logging_sock_deinit_svc();
10781#endif
10782
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010783 return -ENODEV;
10784 }
10785#endif
10786
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010787#ifdef HAVE_CBC_DONE
10788 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10789 msleep(1000);
10790 }
10791 if (max_cbc_retries >= 10) {
10792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10793 }
10794#endif
10795
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 dev = wcnss_wlan_get_device();
10797#endif // ANI_BUS_TYPE_PLATFORM
10798
10799
10800 do {
10801 if (NULL == dev) {
10802 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10803 ret_status = -1;
10804 break;
10805 }
10806
Jeff Johnson295189b2012-06-20 16:38:30 -070010807#ifdef TIMER_MANAGER
10808 vos_timer_manager_init();
10809#endif
10810
10811 /* Preopen VOSS so that it is ready to start at least SAL */
10812 status = vos_preOpen(&pVosContext);
10813
10814 if (!VOS_IS_STATUS_SUCCESS(status))
10815 {
10816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10817 ret_status = -1;
10818 break;
10819 }
10820
Sushant Kaushik02beb352015-06-04 15:15:01 +053010821 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053010822 hdd_register_debug_callback();
10823
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010824#ifndef MODULE
10825 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10826 */
10827 hdd_set_conparam((v_UINT_t)con_mode);
10828#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010829
10830 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010831 if (hdd_wlan_startup(dev))
10832 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010834 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 vos_preClose( &pVosContext );
10836 ret_status = -1;
10837 break;
10838 }
10839
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 } while (0);
10841
10842 if (0 != ret_status)
10843 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010844#ifdef TIMER_MANAGER
10845 vos_timer_exit();
10846#endif
10847#ifdef MEMORY_DEBUG
10848 vos_mem_exit();
10849#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010850 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010851#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10852 wlan_logging_sock_deinit_svc();
10853#endif
10854
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10856 }
10857 else
10858 {
10859 //Send WLAN UP indication to Nlink Service
10860 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10861
10862 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 }
10864
10865 EXIT();
10866
10867 return ret_status;
10868}
10869
Jeff Johnson32d95a32012-09-10 13:15:23 -070010870/**---------------------------------------------------------------------------
10871
10872 \brief hdd_module_init() - Init Function
10873
10874 This is the driver entry point (invoked when module is loaded using insmod)
10875
10876 \param - None
10877
10878 \return - 0 for success, non zero for failure
10879
10880 --------------------------------------------------------------------------*/
10881#ifdef MODULE
10882static int __init hdd_module_init ( void)
10883{
10884 return hdd_driver_init();
10885}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010886#else /* #ifdef MODULE */
10887static int __init hdd_module_init ( void)
10888{
10889 /* Driver initialization is delayed to fwpath_changed_handler */
10890 return 0;
10891}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010892#endif /* #ifdef MODULE */
10893
Jeff Johnson295189b2012-06-20 16:38:30 -070010894
10895/**---------------------------------------------------------------------------
10896
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010897 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010898
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010899 This is the driver exit point (invoked when module is unloaded using rmmod
10900 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010901
10902 \param - None
10903
10904 \return - None
10905
10906 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010907static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010908{
10909 hdd_context_t *pHddCtx = NULL;
10910 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010911 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010912 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
10914 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10915
10916 //Get the global vos context
10917 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10918
10919 if(!pVosContext)
10920 {
10921 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10922 goto done;
10923 }
10924
10925 //Get the HDD context.
10926 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10927
10928 if(!pHddCtx)
10929 {
10930 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10931 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010932 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10933 {
10934 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10935 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10936 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10937 hdd_wlan_exit(pHddCtx);
10938 vos_preClose( &pVosContext );
10939 goto done;
10940 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 else
10942 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010943 /* We wait for active entry threads to exit from driver
10944 * by waiting until rtnl_lock is available.
10945 */
10946 rtnl_lock();
10947 rtnl_unlock();
10948
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010949 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10950 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10951 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10952 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010954 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010955 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10956 msecs_to_jiffies(30000));
10957 if(!rc)
10958 {
10959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10960 "%s:SSR timedout, fatal error", __func__);
10961 VOS_BUG(0);
10962 }
10963 }
10964
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010965 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10966 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010967
c_hpothu8adb97b2014-12-08 19:38:20 +053010968 /* Driver Need to send country code 00 in below condition
10969 * 1) If gCountryCodePriority is set to 1; and last country
10970 * code set is through 11d. This needs to be done in case
10971 * when NV country code is 00.
10972 * This Needs to be done as when kernel store last country
10973 * code and if stored country code is not through 11d,
10974 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10975 * in next load/unload as soon as we get any country through
10976 * 11d. In sme_HandleChangeCountryCodeByUser
10977 * pMsg->countryCode will be last countryCode and
10978 * pMac->scan.countryCode11d will be country through 11d so
10979 * due to mismatch driver will disable 11d.
10980 *
10981 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010982
c_hpothu8adb97b2014-12-08 19:38:20 +053010983 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010984 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010985 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010986 {
10987 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010988 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010989 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10990 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010991
c_hpothu8adb97b2014-12-08 19:38:20 +053010992 //Do all the cleanup before deregistering the driver
10993 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 }
10995
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 vos_preClose( &pVosContext );
10997
10998#ifdef TIMER_MANAGER
10999 vos_timer_exit();
11000#endif
11001#ifdef MEMORY_DEBUG
11002 vos_mem_exit();
11003#endif
11004
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011005#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11006 wlan_logging_sock_deinit_svc();
11007#endif
11008
Jeff Johnson295189b2012-06-20 16:38:30 -070011009done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011010 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011011
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
11013}
11014
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011015/**---------------------------------------------------------------------------
11016
11017 \brief hdd_module_exit() - Exit function
11018
11019 This is the driver exit point (invoked when module is unloaded using rmmod)
11020
11021 \param - None
11022
11023 \return - None
11024
11025 --------------------------------------------------------------------------*/
11026static void __exit hdd_module_exit(void)
11027{
11028 hdd_driver_exit();
11029}
11030
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011031#ifdef MODULE
11032static int fwpath_changed_handler(const char *kmessage,
11033 struct kernel_param *kp)
11034{
Jeff Johnson76052702013-04-16 13:55:05 -070011035 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011036}
11037
11038static int con_mode_handler(const char *kmessage,
11039 struct kernel_param *kp)
11040{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070011041 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011042}
11043#else /* #ifdef MODULE */
11044/**---------------------------------------------------------------------------
11045
Jeff Johnson76052702013-04-16 13:55:05 -070011046 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011047
Jeff Johnson76052702013-04-16 13:55:05 -070011048 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011049 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070011050 - invoked when module parameter fwpath is modified from userspace to signal
11051 initializing the WLAN driver or when con_mode is modified from userspace
11052 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011053
11054 \return - 0 for success, non zero for failure
11055
11056 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070011057static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011058{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011059 int ret_status;
11060
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011061 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011062 ret_status = hdd_driver_init();
11063 wlan_hdd_inited = ret_status ? 0 : 1;
11064 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011065 }
11066
11067 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070011068
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011069 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070011070
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011071 ret_status = hdd_driver_init();
11072 wlan_hdd_inited = ret_status ? 0 : 1;
11073 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011074}
11075
Jeff Johnson295189b2012-06-20 16:38:30 -070011076/**---------------------------------------------------------------------------
11077
Jeff Johnson76052702013-04-16 13:55:05 -070011078 \brief fwpath_changed_handler() - Handler Function
11079
11080 Handle changes to the fwpath parameter
11081
11082 \return - 0 for success, non zero for failure
11083
11084 --------------------------------------------------------------------------*/
11085static int fwpath_changed_handler(const char *kmessage,
11086 struct kernel_param *kp)
11087{
11088 int ret;
11089
11090 ret = param_set_copystring(kmessage, kp);
11091 if (0 == ret)
11092 ret = kickstart_driver();
11093 return ret;
11094}
11095
11096/**---------------------------------------------------------------------------
11097
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011098 \brief con_mode_handler() -
11099
11100 Handler function for module param con_mode when it is changed by userspace
11101 Dynamically linked - do nothing
11102 Statically linked - exit and init driver, as in rmmod and insmod
11103
Jeff Johnson76052702013-04-16 13:55:05 -070011104 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011105
Jeff Johnson76052702013-04-16 13:55:05 -070011106 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011107
11108 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070011109static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011110{
Jeff Johnson76052702013-04-16 13:55:05 -070011111 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011112
Jeff Johnson76052702013-04-16 13:55:05 -070011113 ret = param_set_int(kmessage, kp);
11114 if (0 == ret)
11115 ret = kickstart_driver();
11116 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011117}
11118#endif /* #ifdef MODULE */
11119
11120/**---------------------------------------------------------------------------
11121
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 \brief hdd_get_conparam() -
11123
11124 This is the driver exit point (invoked when module is unloaded using rmmod)
11125
11126 \param - None
11127
11128 \return - tVOS_CON_MODE
11129
11130 --------------------------------------------------------------------------*/
11131tVOS_CON_MODE hdd_get_conparam ( void )
11132{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011133#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011135#else
11136 return (tVOS_CON_MODE)curr_con_mode;
11137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011138}
11139void hdd_set_conparam ( v_UINT_t newParam )
11140{
11141 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011142#ifndef MODULE
11143 curr_con_mode = con_mode;
11144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011145}
11146/**---------------------------------------------------------------------------
11147
11148 \brief hdd_softap_sta_deauth() - function
11149
11150 This to take counter measure to handle deauth req from HDD
11151
11152 \param - pAdapter - Pointer to the HDD
11153
11154 \param - enable - boolean value
11155
11156 \return - None
11157
11158 --------------------------------------------------------------------------*/
11159
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011160VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
11161 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070011162{
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011164 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165
11166 ENTER();
11167
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011168 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
11169 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011170
11171 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011172 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011173 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011174
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011175 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176
11177 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011178 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011179}
11180
11181/**---------------------------------------------------------------------------
11182
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011183 \brief hdd_del_all_sta() - function
11184
11185 This function removes all the stations associated on stopping AP/P2P GO.
11186
11187 \param - pAdapter - Pointer to the HDD
11188
11189 \return - None
11190
11191 --------------------------------------------------------------------------*/
11192
11193int hdd_del_all_sta(hdd_adapter_t *pAdapter)
11194{
11195 v_U16_t i;
11196 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011197 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11198 ptSapContext pSapCtx = NULL;
11199 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11200 if(pSapCtx == NULL){
11201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11202 FL("psapCtx is NULL"));
11203 return 1;
11204 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011205 ENTER();
11206
11207 hddLog(VOS_TRACE_LEVEL_INFO,
11208 "%s: Delete all STAs associated.",__func__);
11209 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11210 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
11211 )
11212 {
11213 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11214 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011215 if ((pSapCtx->aStaInfo[i].isUsed) &&
11216 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011217 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011218 struct tagCsrDelStaParams delStaParams;
11219
11220 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011221 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011222 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11223 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011224 &delStaParams);
11225 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011226 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011227 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011228 }
11229 }
11230 }
11231
11232 EXIT();
11233 return 0;
11234}
11235
11236/**---------------------------------------------------------------------------
11237
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 \brief hdd_softap_sta_disassoc() - function
11239
11240 This to take counter measure to handle deauth req from HDD
11241
11242 \param - pAdapter - Pointer to the HDD
11243
11244 \param - enable - boolean value
11245
11246 \return - None
11247
11248 --------------------------------------------------------------------------*/
11249
11250void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11251{
11252 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11253
11254 ENTER();
11255
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011256 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011257
11258 //Ignore request to disassoc bcmc station
11259 if( pDestMacAddress[0] & 0x1 )
11260 return;
11261
11262 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11263}
11264
11265void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11266{
11267 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11268
11269 ENTER();
11270
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011271 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011272
11273 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11274}
11275
Jeff Johnson295189b2012-06-20 16:38:30 -070011276/**---------------------------------------------------------------------------
11277 *
11278 * \brief hdd_get__concurrency_mode() -
11279 *
11280 *
11281 * \param - None
11282 *
11283 * \return - CONCURRENCY MODE
11284 *
11285 * --------------------------------------------------------------------------*/
11286tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11287{
11288 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11289 hdd_context_t *pHddCtx;
11290
11291 if (NULL != pVosContext)
11292 {
11293 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11294 if (NULL != pHddCtx)
11295 {
11296 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11297 }
11298 }
11299
11300 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011301 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 return VOS_STA;
11303}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011304v_BOOL_t
11305wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11306{
11307 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011308
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011309 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11310 if (pAdapter == NULL)
11311 {
11312 hddLog(VOS_TRACE_LEVEL_INFO,
11313 FL("GO doesn't exist"));
11314 return TRUE;
11315 }
11316 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11317 {
11318 hddLog(VOS_TRACE_LEVEL_INFO,
11319 FL("GO started"));
11320 return TRUE;
11321 }
11322 else
11323 /* wait till GO changes its interface to p2p device */
11324 hddLog(VOS_TRACE_LEVEL_INFO,
11325 FL("Del_bss called, avoid apps suspend"));
11326 return FALSE;
11327
11328}
Jeff Johnson295189b2012-06-20 16:38:30 -070011329/* Decide whether to allow/not the apps power collapse.
11330 * Allow apps power collapse if we are in connected state.
11331 * if not, allow only if we are in IMPS */
11332v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11333{
11334 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011335 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011336 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11338 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11339 hdd_adapter_t *pAdapter = NULL;
11340 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011341 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011342
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11344 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011345
Yathish9f22e662012-12-10 14:21:35 -080011346 concurrent_state = hdd_get_concurrency_mode();
11347
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011348 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11349 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11350 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011351#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011352
Yathish9f22e662012-12-10 14:21:35 -080011353 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011354 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011355 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11356 return TRUE;
11357#endif
11358
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 /*loop through all adapters. TBD fix for Concurrency */
11360 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11361 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11362 {
11363 pAdapter = pAdapterNode->pAdapter;
11364 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11365 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11366 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011367 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011368 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011369 && pmcState != STOPPED && pmcState != STANDBY &&
11370 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011371 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11372 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011374 if(pmcState == FULL_POWER &&
11375 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11376 {
11377 /*
11378 * When SCO indication comes from Coex module , host will
11379 * enter in to full power mode, but this should not prevent
11380 * apps processor power collapse.
11381 */
11382 hddLog(LOG1,
11383 FL("Allow apps power collapse"
11384 "even when sco indication is set"));
11385 return TRUE;
11386 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011387 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011388 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11389 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 return FALSE;
11391 }
11392 }
11393 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11394 pAdapterNode = pNext;
11395 }
11396 return TRUE;
11397}
11398
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011399/* Decides whether to send suspend notification to Riva
11400 * if any adapter is in BMPS; then it is required */
11401v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11402{
11403 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11404 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11405
11406 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11407 {
11408 return TRUE;
11409 }
11410 return FALSE;
11411}
11412
Jeff Johnson295189b2012-06-20 16:38:30 -070011413void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11414{
11415 switch(mode)
11416 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011417 case VOS_STA_MODE:
11418 case VOS_P2P_CLIENT_MODE:
11419 case VOS_P2P_GO_MODE:
11420 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011421 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011422 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 break;
11424 default:
11425 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011427 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11428 "Number of open sessions for mode %d = %d"),
11429 pHddCtx->concurrency_mode, mode,
11430 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011431}
11432
11433
11434void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11435{
11436 switch(mode)
11437 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011438 case VOS_STA_MODE:
11439 case VOS_P2P_CLIENT_MODE:
11440 case VOS_P2P_GO_MODE:
11441 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011442 pHddCtx->no_of_open_sessions[mode]--;
11443 if (!(pHddCtx->no_of_open_sessions[mode]))
11444 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 break;
11446 default:
11447 break;
11448 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011449 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11450 "Number of open sessions for mode %d = %d"),
11451 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11452
11453}
11454/**---------------------------------------------------------------------------
11455 *
11456 * \brief wlan_hdd_incr_active_session()
11457 *
11458 * This function increments the number of active sessions
11459 * maintained per device mode
11460 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11461 * Incase of SAP/P2P GO upon bss start it is incremented
11462 *
11463 * \param pHddCtx - HDD Context
11464 * \param mode - device mode
11465 *
11466 * \return - None
11467 *
11468 * --------------------------------------------------------------------------*/
11469void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11470{
11471 switch (mode) {
11472 case VOS_STA_MODE:
11473 case VOS_P2P_CLIENT_MODE:
11474 case VOS_P2P_GO_MODE:
11475 case VOS_STA_SAP_MODE:
11476 pHddCtx->no_of_active_sessions[mode]++;
11477 break;
11478 default:
11479 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11480 break;
11481 }
11482 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11483 mode,
11484 pHddCtx->no_of_active_sessions[mode]);
11485}
11486
11487/**---------------------------------------------------------------------------
11488 *
11489 * \brief wlan_hdd_decr_active_session()
11490 *
11491 * This function decrements the number of active sessions
11492 * maintained per device mode
11493 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11494 * Incase of SAP/P2P GO upon bss stop it is decremented
11495 *
11496 * \param pHddCtx - HDD Context
11497 * \param mode - device mode
11498 *
11499 * \return - None
11500 *
11501 * --------------------------------------------------------------------------*/
11502void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11503{
Bhargav Shahd0715912015-10-01 18:17:37 +053011504
Agarwal Ashish51325b52014-06-16 16:50:49 +053011505 switch (mode) {
11506 case VOS_STA_MODE:
11507 case VOS_P2P_CLIENT_MODE:
11508 case VOS_P2P_GO_MODE:
11509 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011510 if (pHddCtx->no_of_active_sessions[mode] > 0)
11511 pHddCtx->no_of_active_sessions[mode]--;
11512 else
11513 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11514 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011515 break;
11516 default:
11517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11518 break;
11519 }
11520 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11521 mode,
11522 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011523}
11524
Jeff Johnsone7245742012-09-05 17:12:55 -070011525/**---------------------------------------------------------------------------
11526 *
11527 * \brief wlan_hdd_restart_init
11528 *
11529 * This function initalizes restart timer/flag. An internal function.
11530 *
11531 * \param - pHddCtx
11532 *
11533 * \return - None
11534 *
11535 * --------------------------------------------------------------------------*/
11536
11537static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11538{
11539 /* Initialize */
11540 pHddCtx->hdd_restart_retries = 0;
11541 atomic_set(&pHddCtx->isRestartInProgress, 0);
11542 vos_timer_init(&pHddCtx->hdd_restart_timer,
11543 VOS_TIMER_TYPE_SW,
11544 wlan_hdd_restart_timer_cb,
11545 pHddCtx);
11546}
11547/**---------------------------------------------------------------------------
11548 *
11549 * \brief wlan_hdd_restart_deinit
11550 *
11551 * This function cleans up the resources used. An internal function.
11552 *
11553 * \param - pHddCtx
11554 *
11555 * \return - None
11556 *
11557 * --------------------------------------------------------------------------*/
11558
11559static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11560{
11561
11562 VOS_STATUS vos_status;
11563 /* Block any further calls */
11564 atomic_set(&pHddCtx->isRestartInProgress, 1);
11565 /* Cleanup */
11566 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11567 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011568 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011569 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11570 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011571 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011572
11573}
11574
11575/**---------------------------------------------------------------------------
11576 *
11577 * \brief wlan_hdd_framework_restart
11578 *
11579 * This function uses a cfg80211 API to start a framework initiated WLAN
11580 * driver module unload/load.
11581 *
11582 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11583 *
11584 *
11585 * \param - pHddCtx
11586 *
11587 * \return - VOS_STATUS_SUCCESS: Success
11588 * VOS_STATUS_E_EMPTY: Adapter is Empty
11589 * VOS_STATUS_E_NOMEM: No memory
11590
11591 * --------------------------------------------------------------------------*/
11592
11593static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11594{
11595 VOS_STATUS status = VOS_STATUS_SUCCESS;
11596 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011597 int len = (sizeof (struct ieee80211_mgmt));
11598 struct ieee80211_mgmt *mgmt = NULL;
11599
11600 /* Prepare the DEAUTH managment frame with reason code */
11601 mgmt = kzalloc(len, GFP_KERNEL);
11602 if(mgmt == NULL)
11603 {
11604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11605 "%s: memory allocation failed (%d bytes)", __func__, len);
11606 return VOS_STATUS_E_NOMEM;
11607 }
11608 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011609
11610 /* Iterate over all adapters/devices */
11611 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011612 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11613 {
11614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11615 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11616 goto end;
11617 }
11618
Jeff Johnsone7245742012-09-05 17:12:55 -070011619 do
11620 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011621 if(pAdapterNode->pAdapter &&
11622 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011623 {
11624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11625 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11626 pAdapterNode->pAdapter->dev->name,
11627 pAdapterNode->pAdapter->device_mode,
11628 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011629 /*
11630 * CFG80211 event to restart the driver
11631 *
11632 * 'cfg80211_send_unprot_deauth' sends a
11633 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11634 * of SME(Linux Kernel) state machine.
11635 *
11636 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11637 * the driver.
11638 *
11639 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11641 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11642#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011643 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011644#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011645 }
11646 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11647 pAdapterNode = pNext;
11648 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11649
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011650 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011651 /* Free the allocated management frame */
11652 kfree(mgmt);
11653
Jeff Johnsone7245742012-09-05 17:12:55 -070011654 /* Retry until we unload or reach max count */
11655 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11656 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11657
11658 return status;
11659
11660}
11661/**---------------------------------------------------------------------------
11662 *
11663 * \brief wlan_hdd_restart_timer_cb
11664 *
11665 * Restart timer callback. An internal function.
11666 *
11667 * \param - User data:
11668 *
11669 * \return - None
11670 *
11671 * --------------------------------------------------------------------------*/
11672
11673void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11674{
11675 hdd_context_t *pHddCtx = usrDataForCallback;
11676 wlan_hdd_framework_restart(pHddCtx);
11677 return;
11678
11679}
11680
11681
11682/**---------------------------------------------------------------------------
11683 *
11684 * \brief wlan_hdd_restart_driver
11685 *
11686 * This function sends an event to supplicant to restart the WLAN driver.
11687 *
11688 * This function is called from vos_wlanRestart.
11689 *
11690 * \param - pHddCtx
11691 *
11692 * \return - VOS_STATUS_SUCCESS: Success
11693 * VOS_STATUS_E_EMPTY: Adapter is Empty
11694 * VOS_STATUS_E_ALREADY: Request already in progress
11695
11696 * --------------------------------------------------------------------------*/
11697VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11698{
11699 VOS_STATUS status = VOS_STATUS_SUCCESS;
11700
11701 /* A tight check to make sure reentrancy */
11702 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11703 {
Mihir Shetefd528652014-06-23 19:07:50 +053011704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011705 "%s: WLAN restart is already in progress", __func__);
11706
11707 return VOS_STATUS_E_ALREADY;
11708 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011709 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011710#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011711 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011712#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011713
Jeff Johnsone7245742012-09-05 17:12:55 -070011714 return status;
11715}
11716
Bhargav Shahd0715912015-10-01 18:17:37 +053011717/**
11718 * hdd_get_total_sessions() - provide total number of active sessions
11719 * @pHddCtx: Valid Global HDD context pointer
11720 *
11721 * This function iterates through pAdaptors and find the number of all active
11722 * sessions. This active sessions includes connected sta, p2p client and number
11723 * of client connected to sap/p2p go.
11724 *
11725 * Return: Total number of active sessions.
11726 */
11727v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
11728{
11729 v_U8_t active_session = 0;
11730 hdd_station_ctx_t *pHddStaCtx;
11731 hdd_adapter_list_node_t *pAdapterNode, *pNext;
11732 hdd_adapter_t *pAdapter;
11733 VOS_STATUS status;
11734
11735 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
11736 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
11737 pAdapter = pAdapterNode->pAdapter;
11738 switch (pAdapter->device_mode) {
11739 case VOS_STA_MODE:
11740 case VOS_P2P_CLIENT_MODE:
11741 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11742 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11743 active_session += 1;
11744 break;
11745 case VOS_STA_SAP_MODE:
11746 case VOS_P2P_GO_MODE:
11747 active_session += hdd_softap_get_connected_sta(pAdapter);
11748 break;
11749 default:
11750 break;
11751 }
11752
11753 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11754 pAdapterNode = pNext;
11755 }
11756
11757 return active_session;
11758}
11759
11760/**
11761 * hdd_set_delack_value() - Set delack value
11762 * @pHddCtx: Valid Global HDD context pointer
11763 * @next_rx_level: Value to set for delack
11764 *
11765 * This function compare present value and next value of delack. If the both
11766 * are diffrent then it sets next value .
11767 *
11768 * Return: void.
11769 */
11770void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
11771{
11772 if (pHddCtx->cur_rx_level != next_rx_level) {
11773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11774 "%s: TCP DELACK trigger level %d",
11775 __func__, next_rx_level);
11776 mutex_lock(&pHddCtx->cur_rx_level_lock);
11777 pHddCtx->cur_rx_level = next_rx_level;
11778 mutex_unlock(&pHddCtx->cur_rx_level_lock);
11779 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
11780 sizeof(next_rx_level));
11781 }
11782}
11783
11784/**
11785 * hdd_set_default_stop_delack_timer() - Start delack timer
11786 * @pHddCtx: Valid Global HDD context pointer
11787 *
11788 * This function stop delack timer and set delack value to default..
11789 *
11790 * Return: void.
11791 */
11792
11793void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
11794{
11795 if (VOS_TIMER_STATE_RUNNING !=
11796 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11798 "%s: Can not stop timer", __func__);
11799 return;
11800 }
11801
11802 vos_timer_stop(&pHddCtx->delack_timer);
11803 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
11804}
11805
11806/**
11807 * hdd_start_delack_timer() - Start delack timer
11808 * @pHddCtx: Valid Global HDD context pointer
11809 *
11810 * This function starts the delack timer for tcpDelAckComputeInterval time
11811 * interval.The default timer value is 2 second.
11812 *
11813 * Return: void.
11814 */
11815void hdd_start_delack_timer(hdd_context_t *pHddCtx)
11816{
11817 if (VOS_TIMER_STATE_RUNNING ==
11818 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11820 "%s: Timer is already running", __func__);
11821 return;
11822 }
11823
11824 vos_timer_start(&pHddCtx->delack_timer,
11825 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11826}
11827
11828/**
11829 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
11830 * @pHddCtx: Valid Global HDD context pointer
11831 *
11832 * This function updates the prev_rx_packets count from the corresponding
11833 * pAdapter states. This prev_rx_packets will diffed with the packet count
11834 * at the end of delack timer. That can give number of RX packet is spacific
11835 * time.
11836 *
11837 * Return: void.
11838 */
11839void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
11840{
11841 hdd_adapter_list_node_t *pAdapterNode, *pNext;
11842 hdd_adapter_t *pAdapter;
11843 VOS_STATUS status;
11844
11845 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11846 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
11847 pAdapter = pAdapterNode->pAdapter;
11848 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
11849 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11850 pAdapterNode = pNext;
11851 }
11852}
11853
11854/**
11855 * hdd_manage_delack_timer() - start\stop delack timer
11856 * @pHddCtx: Valid Global HDD context pointer
11857 *
11858 * This function check the number of concerent session present, it starts the
11859 * delack timer if only one session is present.
11860 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
11861 *
11862 * Return: void.
11863 */
11864void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
11865{
11866 uint8_t sessions;
11867
11868 if (!pHddCtx->cfg_ini->enable_delack) {
11869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11870 "%s: TCP DELACK is not enabled", __func__);
11871 return;
11872 }
11873
11874 /* Blindly stop timer of BTCOEX and TDLS Session is up */
11875 if (pHddCtx->mode != 0) {
11876 hdd_set_default_stop_delack_timer(pHddCtx);
11877 return;
11878 }
11879
11880 sessions = hdd_get_total_sessions(pHddCtx);
11881 if (sessions == 1) {
11882 hdd_update_prev_rx_packet_count(pHddCtx);
11883 hdd_start_delack_timer(pHddCtx);
11884 } else {
11885 hdd_set_default_stop_delack_timer(pHddCtx);
11886 }
11887}
11888
Mihir Shetee1093ba2014-01-21 20:13:32 +053011889/**---------------------------------------------------------------------------
11890 *
11891 * \brief wlan_hdd_init_channels
11892 *
11893 * This function is used to initialize the channel list in CSR
11894 *
11895 * This function is called from hdd_wlan_startup
11896 *
11897 * \param - pHddCtx: HDD context
11898 *
11899 * \return - VOS_STATUS_SUCCESS: Success
11900 * VOS_STATUS_E_FAULT: Failure reported by SME
11901
11902 * --------------------------------------------------------------------------*/
11903static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11904{
11905 eHalStatus status;
11906
11907 status = sme_InitChannels(pHddCtx->hHal);
11908 if (HAL_STATUS_SUCCESS(status))
11909 {
11910 return VOS_STATUS_SUCCESS;
11911 }
11912 else
11913 {
11914 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11915 __func__, status);
11916 return VOS_STATUS_E_FAULT;
11917 }
11918}
11919
Mihir Shete04206452014-11-20 17:50:58 +053011920#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011921VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011922{
11923 eHalStatus status;
11924
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011925 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011926 if (HAL_STATUS_SUCCESS(status))
11927 {
11928 return VOS_STATUS_SUCCESS;
11929 }
11930 else
11931 {
11932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11933 __func__, status);
11934 return VOS_STATUS_E_FAULT;
11935 }
11936}
Mihir Shete04206452014-11-20 17:50:58 +053011937#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011938/*
11939 * API to find if there is any STA or P2P-Client is connected
11940 */
11941VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11942{
11943 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11944}
Jeff Johnsone7245742012-09-05 17:12:55 -070011945
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011946
11947/*
11948 * API to find if the firmware will send logs using DXE channel
11949 */
11950v_U8_t hdd_is_fw_logging_enabled(void)
11951{
11952 hdd_context_t *pHddCtx;
11953
11954 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11955 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11956
Sachin Ahuja084313e2015-05-21 17:57:10 +053011957 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011958}
11959
Agarwal Ashish57e84372014-12-05 18:26:53 +053011960/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011961 * API to find if the firmware will send trace logs using DXE channel
11962 */
11963v_U8_t hdd_is_fw_ev_logging_enabled(void)
11964{
11965 hdd_context_t *pHddCtx;
11966
11967 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11968 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11969
11970 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11971}
11972/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011973 * API to find if there is any session connected
11974 */
11975VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11976{
11977 return sme_is_any_session_connected(pHddCtx->hHal);
11978}
11979
11980
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011981int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11982{
11983 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11984 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011985 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011986 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011987
11988 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011989 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011990 if (pScanInfo->mScanPending)
11991 {
c_hpothua3d45d52015-01-05 14:11:17 +053011992 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11993 eCSR_SCAN_ABORT_DEFAULT);
11994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11995 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011996
c_hpothua3d45d52015-01-05 14:11:17 +053011997 /* If there is active scan command lets wait for the completion else
11998 * there is no need to wait as scan command might be in the SME pending
11999 * command list.
12000 */
12001 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
12002 {
c_hpothua3d45d52015-01-05 14:11:17 +053012003 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012004 &pScanInfo->abortscan_event_var,
12005 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053012006 if (0 >= status)
12007 {
12008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053012009 "%s: Timeout or Interrupt occurred while waiting for abort"
12010 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053012011 return -ETIMEDOUT;
12012 }
12013 }
12014 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
12015 {
12016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12017 FL("hdd_abort_mac_scan failed"));
12018 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012019 }
12020 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053012021 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012022}
12023
Abhishek Singh7d624e12015-11-30 14:29:27 +053012024/**
12025 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
12026 * user space
12027 * @frame_ind: Management frame data to be informed.
12028 *
12029 * This function is used to indicate management frame to
12030 * user space
12031 *
12032 * Return: None
12033 *
12034 */
12035void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
12036{
12037 hdd_context_t *hdd_ctx = NULL;
12038 hdd_adapter_t *adapter = NULL;
12039 v_CONTEXT_t vos_context = NULL;
12040
12041 /* Get the global VOSS context.*/
12042 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12043 if (!vos_context) {
12044 hddLog(LOGE, FL("Global VOS context is Null"));
12045 return;
12046 }
12047 /* Get the HDD context.*/
12048 hdd_ctx =
12049 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
12050
12051 if (0 != wlan_hdd_validate_context(hdd_ctx))
12052 {
12053 return;
12054 }
12055 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
12056 frame_ind->sessionId);
12057
12058 if ((NULL != adapter) &&
12059 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
12060 __hdd_indicate_mgmt_frame(adapter,
12061 frame_ind->frameLen,
12062 frame_ind->frameBuf,
12063 frame_ind->frameType,
12064 frame_ind->rxChan,
12065 frame_ind->rxRssi);
12066 return;
12067
12068}
12069
c_hpothu225aa7c2014-10-22 17:45:13 +053012070VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
12071{
12072 hdd_adapter_t *pAdapter;
12073 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12074 VOS_STATUS vosStatus;
12075
12076 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12077 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
12078 {
12079 pAdapter = pAdapterNode->pAdapter;
12080 if (NULL != pAdapter)
12081 {
12082 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
12083 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12084 WLAN_HDD_P2P_GO == pAdapter->device_mode)
12085 {
12086 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
12087 pAdapter->device_mode);
12088 if (VOS_STATUS_SUCCESS !=
12089 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
12090 {
12091 hddLog(LOGE, FL("failed to abort ROC"));
12092 return VOS_STATUS_E_FAILURE;
12093 }
12094 }
12095 }
12096 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12097 pAdapterNode = pNext;
12098 }
12099 return VOS_STATUS_SUCCESS;
12100}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053012101
Mihir Shete0be28772015-02-17 18:42:14 +053012102hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
12103{
12104 hdd_adapter_t *pAdapter;
12105 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12106 hdd_cfg80211_state_t *cfgState;
12107 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
12108 VOS_STATUS vosStatus;
12109
12110 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
12111 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
12112 {
12113 pAdapter = pAdapterNode->pAdapter;
12114 if (NULL != pAdapter)
12115 {
12116 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
12117 pRemainChanCtx = cfgState->remain_on_chan_ctx;
12118 if (pRemainChanCtx)
12119 break;
12120 }
12121 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
12122 pAdapterNode = pNext;
12123 }
12124 return pRemainChanCtx;
12125}
12126
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053012127/**
12128 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
12129 *
12130 * @pHddCtx: HDD context within host driver
12131 * @dfsScanMode: dfsScanMode passed from ioctl
12132 *
12133 */
12134
12135VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
12136 tANI_U8 dfsScanMode)
12137{
12138 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12139 hdd_adapter_t *pAdapter;
12140 VOS_STATUS vosStatus;
12141 hdd_station_ctx_t *pHddStaCtx;
12142 eHalStatus status = eHAL_STATUS_SUCCESS;
12143
12144 if(!pHddCtx)
12145 {
12146 hddLog(LOGE, FL("HDD context is Null"));
12147 return eHAL_STATUS_FAILURE;
12148 }
12149
12150 if (pHddCtx->scan_info.mScanPending)
12151 {
12152 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
12153 pHddCtx->scan_info.sessionId);
12154 hdd_abort_mac_scan(pHddCtx,
12155 pHddCtx->scan_info.sessionId,
12156 eCSR_SCAN_ABORT_DEFAULT);
12157 }
12158
12159 if (!dfsScanMode)
12160 {
12161 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
12162 while ((NULL != pAdapterNode) &&
12163 (VOS_STATUS_SUCCESS == vosStatus))
12164 {
12165 pAdapter = pAdapterNode->pAdapter;
12166
12167 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
12168 {
12169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12170
12171 if(!pHddStaCtx)
12172 {
12173 hddLog(LOGE, FL("HDD STA context is Null"));
12174 return eHAL_STATUS_FAILURE;
12175 }
12176
12177 /* if STA is already connected on DFS channel,
12178 disconnect immediately*/
12179 if (hdd_connIsConnected(pHddStaCtx) &&
12180 (NV_CHANNEL_DFS ==
12181 vos_nv_getChannelEnabledState(
12182 pHddStaCtx->conn_info.operationChannel)))
12183 {
12184 status = sme_RoamDisconnect(pHddCtx->hHal,
12185 pAdapter->sessionId,
12186 eCSR_DISCONNECT_REASON_UNSPECIFIED);
12187 hddLog(LOG1, FL("Client connected on DFS channel %d,"
12188 "sme_RoamDisconnect returned with status: %d"
12189 "for sessionid: %d"), pHddStaCtx->conn_info.
12190 operationChannel, status, pAdapter->sessionId);
12191 }
12192 }
12193
12194 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
12195 &pNext);
12196 pAdapterNode = pNext;
12197 }
12198 }
12199
12200 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
12201 sme_UpdateDFSRoamMode(pHddCtx->hHal,
12202 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
12203
12204 status = sme_HandleDFSChanScan(pHddCtx->hHal);
12205 if (!HAL_STATUS_SUCCESS(status))
12206 {
12207 hddLog(LOGE,
12208 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
12209 return status;
12210 }
12211
12212 return status;
12213}
12214
Nirav Shah7e3c8132015-06-22 23:51:42 +053012215static int hdd_log2_ceil(unsigned value)
12216{
12217 /* need to switch to unsigned math so that negative values
12218 * will right-shift towards 0 instead of -1
12219 */
12220 unsigned tmp = value;
12221 int log2 = -1;
12222
12223 if (value == 0)
12224 return 0;
12225
12226 while (tmp) {
12227 log2++;
12228 tmp >>= 1;
12229 }
12230 if (1U << log2 != value)
12231 log2++;
12232
12233 return log2;
12234}
12235
12236/**
12237 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
12238 * @pAdapter: adapter handle
12239 *
12240 * Return: vos status
12241 */
12242VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
12243{
12244 int hash_elem, log2, i;
12245
12246 spin_lock_bh( &pAdapter->sta_hash_lock);
12247 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
12248 spin_unlock_bh( &pAdapter->sta_hash_lock);
12249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12250 "%s: hash already attached for session id %d",
12251 __func__, pAdapter->sessionId);
12252 return VOS_STATUS_SUCCESS;
12253 }
12254 spin_unlock_bh( &pAdapter->sta_hash_lock);
12255
12256 hash_elem = WLAN_MAX_STA_COUNT;
12257 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
12258 log2 = hdd_log2_ceil(hash_elem);
12259 hash_elem = 1 << log2;
12260
12261 pAdapter->sta_id_hash.mask = hash_elem - 1;
12262 pAdapter->sta_id_hash.idx_bits = log2;
12263 pAdapter->sta_id_hash.bins =
12264 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
12265 if (!pAdapter->sta_id_hash.bins) {
12266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12267 "%s: malloc failed for session %d",
12268 __func__, pAdapter->sessionId);
12269 return VOS_STATUS_E_NOMEM;
12270 }
12271
12272 for (i = 0; i < hash_elem; i++)
12273 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
12274
12275 spin_lock_bh( &pAdapter->sta_hash_lock);
12276 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
12277 spin_unlock_bh( &pAdapter->sta_hash_lock);
12278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12279 "%s: Station ID Hash attached for session id %d",
12280 __func__, pAdapter->sessionId);
12281
12282 return VOS_STATUS_SUCCESS;
12283}
12284
12285/**
12286 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
12287 * @pAdapter: adapter handle
12288 *
12289 * Return: vos status
12290 */
12291VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
12292{
12293 int hash_elem, i;
12294 v_SIZE_t size;
12295
12296 spin_lock_bh( &pAdapter->sta_hash_lock);
12297 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12298 spin_unlock_bh( &pAdapter->sta_hash_lock);
12299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12300 "%s: hash not initialized for session id %d",
12301 __func__, pAdapter->sessionId);
12302 return VOS_STATUS_SUCCESS;
12303 }
12304
12305 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
12306 spin_unlock_bh( &pAdapter->sta_hash_lock);
12307
12308 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
12309
12310 /* free all station info*/
12311 for (i = 0; i < hash_elem; i++) {
12312 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
12313 if (size != 0) {
12314 VOS_STATUS status;
12315 hdd_staid_hash_node_t *sta_info_node = NULL;
12316 hdd_staid_hash_node_t *next_node = NULL;
12317 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
12318 (hdd_list_node_t**) &sta_info_node );
12319
12320 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12321 {
12322 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
12323 &sta_info_node->node);
12324 vos_mem_free(sta_info_node);
12325
12326 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
12327 (hdd_list_node_t*)sta_info_node,
12328 (hdd_list_node_t**)&next_node);
12329 sta_info_node = next_node;
12330 }
12331 }
12332 }
12333
12334 vos_mem_free(pAdapter->sta_id_hash.bins);
12335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12336 "%s: Station ID Hash detached for session id %d",
12337 __func__, pAdapter->sessionId);
12338 return VOS_STATUS_SUCCESS;
12339}
12340
12341/**
12342 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
12343 * @pAdapter: adapter handle
12344 * @mac_addr_in: input mac address
12345 *
12346 * Return: index derived from mac address
12347 */
12348int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
12349 v_MACADDR_t *mac_addr_in)
12350{
12351 uint16 index;
12352 struct hdd_align_mac_addr_t * mac_addr =
12353 (struct hdd_align_mac_addr_t *)mac_addr_in;
12354
12355 index = mac_addr->bytes_ab ^
12356 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
12357 index ^= index >> pAdapter->sta_id_hash.idx_bits;
12358 index &= pAdapter->sta_id_hash.mask;
12359 return index;
12360}
12361
12362/**
12363 * hdd_sta_id_hash_add_entry() - add entry in hash
12364 * @pAdapter: adapter handle
12365 * @sta_id: station id
12366 * @mac_addr: mac address
12367 *
12368 * Return: vos status
12369 */
12370VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
12371 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12372{
12373 uint16 index;
12374 hdd_staid_hash_node_t *sta_info_node = NULL;
12375
Nirav Shah7e3c8132015-06-22 23:51:42 +053012376 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12377 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
12378 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053012379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12380 "%s: malloc failed", __func__);
12381 return VOS_STATUS_E_NOMEM;
12382 }
12383
12384 sta_info_node->sta_id = sta_id;
12385 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
12386
Nirav Shah303ed5c2015-08-24 10:29:25 +053012387 spin_lock_bh( &pAdapter->sta_hash_lock);
12388 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12389 spin_unlock_bh( &pAdapter->sta_hash_lock);
12390 vos_mem_free(sta_info_node);
12391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12392 "%s: hash is not initialized for session id %d",
12393 __func__, pAdapter->sessionId);
12394 return VOS_STATUS_E_FAILURE;
12395 }
12396
Nirav Shah7e3c8132015-06-22 23:51:42 +053012397 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
12398 (hdd_list_node_t*) sta_info_node );
12399 spin_unlock_bh( &pAdapter->sta_hash_lock);
12400 return VOS_STATUS_SUCCESS;
12401}
12402
12403/**
12404 * hdd_sta_id_hash_remove_entry() - remove entry from hash
12405 * @pAdapter: adapter handle
12406 * @sta_id: station id
12407 * @mac_addr: mac address
12408 *
12409 * Return: vos status
12410 */
12411VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
12412 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12413{
12414 uint16 index;
12415 VOS_STATUS status;
12416 hdd_staid_hash_node_t *sta_info_node = NULL;
12417 hdd_staid_hash_node_t *next_node = NULL;
12418
12419 spin_lock_bh( &pAdapter->sta_hash_lock);
12420 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12421 spin_unlock_bh( &pAdapter->sta_hash_lock);
12422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12423 "%s: hash is not initialized for session id %d",
12424 __func__, pAdapter->sessionId);
12425 return VOS_STATUS_E_FAILURE;
12426 }
12427
12428 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12429 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12430 (hdd_list_node_t**) &sta_info_node );
12431
12432 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12433 {
12434 if (sta_info_node->sta_id == sta_id) {
12435 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
12436 &sta_info_node->node);
12437 vos_mem_free(sta_info_node);
12438 break;
12439 }
12440 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12441 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12442 sta_info_node = next_node;
12443 }
12444 spin_unlock_bh( &pAdapter->sta_hash_lock);
12445 return status;
12446}
12447
12448/**
12449 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12450 * @pAdapter: adapter handle
12451 * @mac_addr_in: mac address
12452 *
12453 * Return: station id
12454 */
12455int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12456 v_MACADDR_t *mac_addr_in)
12457{
12458 uint8 is_found = 0;
12459 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12460 uint16 index;
12461 VOS_STATUS status;
12462 hdd_staid_hash_node_t *sta_info_node = NULL;
12463 hdd_staid_hash_node_t *next_node = NULL;
12464
12465 spin_lock_bh( &pAdapter->sta_hash_lock);
12466 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12467 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053012468 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053012469 FL("hash is not initialized for session id %d"),
12470 pAdapter->sessionId);
12471 return HDD_WLAN_INVALID_STA_ID;
12472 }
12473
12474 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12475 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12476 (hdd_list_node_t**) &sta_info_node );
12477
12478 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12479 {
12480 if (vos_mem_compare(&sta_info_node->mac_addr,
12481 mac_addr_in, sizeof(v_MACADDR_t))) {
12482 is_found = 1;
12483 sta_id = sta_info_node->sta_id;
12484 break;
12485 }
12486 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12487 (hdd_list_node_t*)sta_info_node,
12488 (hdd_list_node_t**)&next_node);
12489 sta_info_node = next_node;
12490 }
12491 spin_unlock_bh( &pAdapter->sta_hash_lock);
12492 return sta_id;
12493}
12494
c_manjeecfd1efb2015-09-25 19:32:34 +053012495/*FW memory dump feature*/
12496/**
12497 * This structure hold information about the /proc file
12498 *
12499 */
12500static struct proc_dir_entry *proc_file, *proc_dir;
12501
12502/**
12503 * memdump_read() - perform read operation in memory dump proc file
12504 *
12505 * @file - handle for the proc file.
12506 * @buf - pointer to user space buffer.
12507 * @count - number of bytes to be read.
12508 * @pos - offset in the from buffer.
12509 *
12510 * This function performs read operation for the memory dump proc file.
12511 *
12512 * Return: number of bytes read on success, error code otherwise.
12513 */
12514static ssize_t memdump_read(struct file *file, char __user *buf,
12515 size_t count, loff_t *pos)
12516{
12517 int status;
12518 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
12519 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053012520 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053012521 ENTER();
12522
12523 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
12524 status = wlan_hdd_validate_context(hdd_ctx);
12525 if (0 != status) {
12526 return -EINVAL;
12527 }
12528
12529 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
12530 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
12531 return -EINVAL;
12532 }
12533
12534 /* run fs_read_handler in an atomic context*/
12535 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053012536 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
12537 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053012538 {
12539 /*Free the fwr mem dump buffer */
12540 wlan_free_fwr_mem_dump_buffer();
12541 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053012542 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053012543 }
12544 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
12545 vos_ssr_unprotect(__func__);
12546 EXIT();
12547 return ret_count;
12548}
12549
12550/**
12551 * struct memdump_fops - file operations for memory dump feature
12552 * @read - read function for memory dump operation.
12553 *
12554 * This structure initialize the file operation handle for memory
12555 * dump feature
12556 */
12557static const struct file_operations memdump_fops = {
12558 read: memdump_read
12559};
12560
12561/*
12562* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
12563* To be passed by HDD to WDA and called upon receiving of response
12564* from firmware
12565* @fwMemDumpReqContext : memory dump request context
12566* @dump_rsp : dump response from HAL
12567* Returns none
12568*/
12569void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
12570 tAniFwrDumpRsp *dump_rsp)
12571{
c_manjeef1495642015-10-13 18:35:01 +053012572 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053012573
c_manjeef1495642015-10-13 18:35:01 +053012574 ENTER();
12575 spin_lock(&hdd_context_lock);
12576 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
12577 spin_unlock(&hdd_context_lock);
12578 return;
12579 }
12580 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053012581 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053012582 hddLog(LOGE, FL("fw dump request declined by fwr"));
12583 //set the request completion variable
12584 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053012585 //Free the allocated fwr dump
12586 wlan_free_fwr_mem_dump_buffer();
12587 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053012588 }
c_manjeef1495642015-10-13 18:35:01 +053012589 else {
12590 hddLog(LOG1, FL("fw dump request accepted by fwr"));
12591 /* register the HDD callback which will be called by SVC */
12592 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
12593 }
12594 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012595 EXIT();
12596
12597}
12598
12599/**
12600 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
12601 *
12602 * This function removes file/dir under proc file system that was
12603 * processing firmware memory dump
12604 *
12605 * Return: None
12606 */
12607static void memdump_procfs_remove(void)
12608{
12609 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12610 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
12611 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12612 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12613 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
12614}
12615
12616/**
12617 * memdump_procfs_init() - Initialize procfs for memory dump
12618 *
12619 * @vos_ctx - Global vos context.
12620 *
12621 * This function create file under proc file system to be used later for
12622 * processing firmware memory dump
12623 *
12624 * Return: 0 on success, error code otherwise.
12625 */
12626static int memdump_procfs_init(void *vos_ctx)
12627{
12628 hdd_context_t *hdd_ctx;
12629
12630 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12631 if (!hdd_ctx) {
12632 hddLog(LOGE , FL("Invalid HDD context"));
12633 return -EINVAL;
12634 }
12635
12636 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
12637 if (proc_dir == NULL) {
12638 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12639 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12640 PROCFS_MEMDUMP_DIR);
12641 return -ENOMEM;
12642 }
12643
12644 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
12645 S_IRUSR | S_IWUSR, proc_dir,
12646 &memdump_fops, hdd_ctx);
12647 if (proc_file == NULL) {
12648 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12649 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12650 PROCFS_MEMDUMP_NAME);
12651 return -ENOMEM;
12652 }
12653
12654 hddLog(LOG1 , FL("/proc/%s/%s created"),
12655 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12656
12657 return 0;
12658}
12659
12660/**
12661 * memdump_init() - Initialization function for memory dump feature
12662 *
12663 * This function creates proc file for memdump feature and registers
12664 * HDD callback function with SME.
12665 *
12666 * Return - 0 on success, error otherwise
12667 */
12668int memdump_init(void)
12669{
12670 hdd_context_t *hdd_ctx;
12671 void *vos_ctx;
12672 int status = 0;
12673
12674 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12675 if (!vos_ctx) {
12676 hddLog(LOGE, FL("Invalid VOS context"));
12677 return -EINVAL;
12678 }
12679
12680 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12681 if (!hdd_ctx) {
12682 hddLog(LOGE , FL("Invalid HDD context"));
12683 return -EINVAL;
12684 }
12685
12686 status = memdump_procfs_init(vos_ctx);
12687 if (status) {
12688 hddLog(LOGE , FL("Failed to create proc file"));
12689 return status;
12690 }
12691
12692 return 0;
12693}
12694
12695/**
12696 * memdump_deinit() - De initialize memdump feature
12697 *
12698 * This function removes proc file created for memdump feature.
12699 *
12700 * Return: None
12701 */
12702int memdump_deinit(void)
12703{
12704 hdd_context_t *hdd_ctx;
12705 void *vos_ctx;
12706
12707 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12708 if (!vos_ctx) {
12709 hddLog(LOGE, FL("Invalid VOS context"));
12710 return -EINVAL;
12711 }
12712
12713 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12714 if(!hdd_ctx) {
12715 hddLog(LOGE , FL("Invalid HDD context"));
12716 return -EINVAL;
12717 }
12718
12719 memdump_procfs_remove();
12720 return 0;
12721}
12722
12723/**
12724 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
12725 * Return: HAL status
12726 */
12727
12728int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
12729{
12730 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053012731 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012732 eHalStatus status = eHAL_STATUS_FAILURE;
12733 int ret=0;
12734 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053012735
c_manjeecfd1efb2015-09-25 19:32:34 +053012736 /*Check whether a dump request is already going on
12737 *Caution this function will free previously held memory if new dump request is allowed*/
12738 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
12739 hddLog(LOGE, FL("Fw memdump already in progress"));
12740 return -EBUSY;
12741 }
12742 //Allocate memory for fw mem dump buffer
12743 ret = wlan_fwr_mem_dump_buffer_allocation();
12744 if(ret == -EFAULT)
12745 {
12746 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
12747 return ret;
12748 }
12749 if (0 != ret) {
12750 hddLog(LOGE, FL("Fwr mem Allocation failed"));
12751 return -ENOMEM;
12752 }
c_manjeef1495642015-10-13 18:35:01 +053012753 init_completion(&fw_mem_dump_ctx.req_completion);
12754 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
12755 fw_mem_dump_ctx.status = false;
12756
c_manjeecfd1efb2015-09-25 19:32:34 +053012757 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053012758 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012759 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
12760 if(eHAL_STATUS_SUCCESS != status)
12761 {
12762 hddLog(VOS_TRACE_LEVEL_ERROR,
12763 "%s: fw_mem_dump_req failed ", __func__);
12764 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053012765 ret = -EFAULT;
12766 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053012767 }
c_manjeef1495642015-10-13 18:35:01 +053012768 /*wait for fw mem dump completion to send event to userspace*/
12769 ret = wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
12770 if (0 >= ret )
12771 {
12772 hddLog(VOS_TRACE_LEVEL_ERROR,
12773 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
12774 }
12775cleanup:
12776 spin_lock(&hdd_context_lock);
12777 fw_mem_dump_ctx.magic = 0;
12778 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012779
c_manjeef1495642015-10-13 18:35:01 +053012780 EXIT();
12781 return fw_mem_dump_ctx.status;
12782}
12783
12784/**
12785 * HDD callback which will be called by SVC to indicate mem dump completion.
12786 */
12787void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
12788{
12789 if (!pHddFwMemDumpCtx) {
12790 hddLog(VOS_TRACE_LEVEL_ERROR,
12791 "%s: HDD context not valid ", __func__);
12792 return;
12793 }
12794 spin_lock(&hdd_context_lock);
12795 /* check the req magic and set status */
12796 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
12797 {
12798 pHddFwMemDumpCtx->status = true;
12799 //signal the completion
12800 complete(&(pHddFwMemDumpCtx->req_completion));
12801 }
12802 else
12803 {
12804 hddLog(VOS_TRACE_LEVEL_ERROR,
12805 "%s: fw mem dump request possible timeout ", __func__);
12806 }
12807 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012808}
12809
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012810void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
12811{
12812 if (NULL == pAdapter)
12813 {
12814 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
12815 return;
12816 }
12817 init_completion(&pAdapter->session_open_comp_var);
12818 init_completion(&pAdapter->session_close_comp_var);
12819 init_completion(&pAdapter->disconnect_comp_var);
12820 init_completion(&pAdapter->linkup_event_var);
12821 init_completion(&pAdapter->cancel_rem_on_chan_var);
12822 init_completion(&pAdapter->rem_on_chan_ready_event);
12823 init_completion(&pAdapter->pno_comp_var);
12824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12825 init_completion(&pAdapter->offchannel_tx_event);
12826#endif
12827 init_completion(&pAdapter->tx_action_cnf_event);
12828#ifdef FEATURE_WLAN_TDLS
12829 init_completion(&pAdapter->tdls_add_station_comp);
12830 init_completion(&pAdapter->tdls_del_station_comp);
12831 init_completion(&pAdapter->tdls_mgmt_comp);
12832 init_completion(&pAdapter->tdls_link_establish_req_comp);
12833#endif
12834
12835#ifdef WLAN_FEATURE_RMC
12836 init_completion(&pAdapter->ibss_peer_info_comp);
12837#endif /* WLAN_FEATURE_RMC */
12838 init_completion(&pAdapter->ula_complete);
12839 init_completion(&pAdapter->change_country_code);
12840
12841#ifdef FEATURE_WLAN_BATCH_SCAN
12842 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
12843 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
12844#endif
12845
12846 return;
12847}
c_manjeecfd1efb2015-09-25 19:32:34 +053012848
12849
Jeff Johnson295189b2012-06-20 16:38:30 -070012850//Register the module init/exit functions
12851module_init(hdd_module_init);
12852module_exit(hdd_module_exit);
12853
12854MODULE_LICENSE("Dual BSD/GPL");
12855MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12856MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12857
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012858module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12859 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012860
Jeff Johnson76052702013-04-16 13:55:05 -070012861module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012862 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012863
12864module_param(enable_dfs_chan_scan, int,
12865 S_IRUSR | S_IRGRP | S_IROTH);
12866
12867module_param(enable_11d, int,
12868 S_IRUSR | S_IRGRP | S_IROTH);
12869
12870module_param(country_code, charp,
12871 S_IRUSR | S_IRGRP | S_IROTH);