blob: ccae30250bec5e8c7e09e9f85b21e7ee01537b7c [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;
4406 sscanf(value, "%d", &set_value);
4407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4408 "%s: Tdls offchannel mode:%d",
4409 __func__, set_value);
4410 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4411 if (ret < 0)
4412 {
4413 ret = -EINVAL;
4414 goto exit;
4415 }
4416 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4417 tANI_U8 *value = command;
4418 int set_value;
4419 /* Move pointer to ahead of TDLSOFFCH*/
4420 value += 14;
4421 sscanf(value, "%d", &set_value);
4422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4423 "%s: Tdls offchannel num: %d",
4424 __func__, set_value);
4425 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4426 if (ret < 0)
4427 {
4428 ret = -EINVAL;
4429 goto exit;
4430 }
4431 }
4432#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304433 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4434 {
4435 eHalStatus status;
4436 char *buf = NULL;
4437 char len;
4438 long waitRet;
4439 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304440 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304441 tANI_U8 *ptr = command;
4442 int stats = *(ptr + 11) - '0';
4443
4444 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4445 if (!IS_FEATURE_FW_STATS_ENABLE)
4446 {
4447 hddLog(VOS_TRACE_LEVEL_INFO,
4448 FL("Get Firmware stats feature not supported"));
4449 ret = -EINVAL;
4450 goto exit;
4451 }
4452
4453 if (FW_STATS_MAX <= stats || 0 >= stats)
4454 {
4455 hddLog(VOS_TRACE_LEVEL_INFO,
4456 FL(" stats %d not supported"),stats);
4457 ret = -EINVAL;
4458 goto exit;
4459 }
4460
4461 init_completion(&(fwStatsCtx.completion));
4462 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4463 fwStatsCtx.pAdapter = pAdapter;
4464 fwStatsRsp->type = 0;
4465 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304466 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304467 if (eHAL_STATUS_SUCCESS != status)
4468 {
4469 hddLog(VOS_TRACE_LEVEL_ERROR,
4470 FL(" fail to post WDA cmd status = %d"), status);
4471 ret = -EINVAL;
4472 goto exit;
4473 }
4474 waitRet = wait_for_completion_timeout
4475 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4476 if (waitRet <= 0)
4477 {
4478 hddLog(VOS_TRACE_LEVEL_ERROR,
4479 FL("failed to wait on GwtFwstats"));
4480 //Make magic number to zero so that callback is not executed.
4481 spin_lock(&hdd_context_lock);
4482 fwStatsCtx.magic = 0x0;
4483 spin_unlock(&hdd_context_lock);
4484 ret = -EINVAL;
4485 goto exit;
4486 }
4487 if (fwStatsRsp->type)
4488 {
4489 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4490 if (!buf)
4491 {
4492 hddLog(VOS_TRACE_LEVEL_ERROR,
4493 FL(" failed to allocate memory"));
4494 ret = -ENOMEM;
4495 goto exit;
4496 }
4497 switch( fwStatsRsp->type )
4498 {
4499 case FW_UBSP_STATS:
4500 {
4501 len = snprintf(buf, FW_STATE_RSP_LEN,
4502 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304503 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4504 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304505 }
4506 break;
4507 default:
4508 {
4509 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4510 ret = -EFAULT;
4511 kfree(buf);
4512 goto exit;
4513 }
4514 }
4515 if (copy_to_user(priv_data.buf, buf, len + 1))
4516 {
4517 hddLog(VOS_TRACE_LEVEL_ERROR,
4518 FL(" failed to copy data to user buffer"));
4519 ret = -EFAULT;
4520 kfree(buf);
4521 goto exit;
4522 }
4523 ret = len;
4524 kfree(buf);
4525 }
4526 else
4527 {
4528 hddLog(VOS_TRACE_LEVEL_ERROR,
4529 FL("failed to fetch the stats"));
4530 ret = -EFAULT;
4531 goto exit;
4532 }
4533
4534 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304535 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4536 {
4537 /*
4538 * this command wld be called by user-space when it detects WLAN
4539 * ON after airplane mode is set. When APM is set, WLAN turns off.
4540 * But it can be turned back on. Otherwise; when APM is turned back
4541 * off, WLAN wld turn back on. So at that point the command is
4542 * expected to come down. 0 means disable, 1 means enable. The
4543 * constraint is removed when parameter 1 is set or different
4544 * country code is set
4545 */
4546 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4547 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05304548 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4549 {
4550 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4551 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004552 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4554 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4555 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304556 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4557 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004559 }
4560exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304561 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004562 if (command)
4563 {
4564 kfree(command);
4565 }
4566 return ret;
4567}
4568
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004569#ifdef CONFIG_COMPAT
4570static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4571{
4572 struct {
4573 compat_uptr_t buf;
4574 int used_len;
4575 int total_len;
4576 } compat_priv_data;
4577 hdd_priv_data_t priv_data;
4578 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004579
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004580 /*
4581 * Note that pAdapter and ifr have already been verified by caller,
4582 * and HDD context has also been validated
4583 */
4584 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4585 sizeof(compat_priv_data))) {
4586 ret = -EFAULT;
4587 goto exit;
4588 }
4589 priv_data.buf = compat_ptr(compat_priv_data.buf);
4590 priv_data.used_len = compat_priv_data.used_len;
4591 priv_data.total_len = compat_priv_data.total_len;
4592 ret = hdd_driver_command(pAdapter, &priv_data);
4593 exit:
4594 return ret;
4595}
4596#else /* CONFIG_COMPAT */
4597static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4598{
4599 /* will never be invoked */
4600 return 0;
4601}
4602#endif /* CONFIG_COMPAT */
4603
4604static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4605{
4606 hdd_priv_data_t priv_data;
4607 int ret = 0;
4608
4609 /*
4610 * Note that pAdapter and ifr have already been verified by caller,
4611 * and HDD context has also been validated
4612 */
4613 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4614 ret = -EFAULT;
4615 } else {
4616 ret = hdd_driver_command(pAdapter, &priv_data);
4617 }
4618 return ret;
4619}
4620
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304621int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004622{
4623 hdd_adapter_t *pAdapter;
4624 hdd_context_t *pHddCtx;
4625 int ret;
4626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304627 ENTER();
4628
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004629 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4630 if (NULL == pAdapter) {
4631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4632 "%s: HDD adapter context is Null", __func__);
4633 ret = -ENODEV;
4634 goto exit;
4635 }
4636 if (dev != pAdapter->dev) {
4637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4638 "%s: HDD adapter/dev inconsistency", __func__);
4639 ret = -ENODEV;
4640 goto exit;
4641 }
4642
4643 if ((!ifr) || (!ifr->ifr_data)) {
4644 ret = -EINVAL;
4645 goto exit;
4646 }
4647
4648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4649 ret = wlan_hdd_validate_context(pHddCtx);
4650 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004651 ret = -EBUSY;
4652 goto exit;
4653 }
4654
4655 switch (cmd) {
4656 case (SIOCDEVPRIVATE + 1):
4657 if (is_compat_task())
4658 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4659 else
4660 ret = hdd_driver_ioctl(pAdapter, ifr);
4661 break;
4662 default:
4663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4664 __func__, cmd);
4665 ret = -EINVAL;
4666 break;
4667 }
4668 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304669 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004670 return ret;
4671}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004672
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304673int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4674{
4675 int ret;
4676
4677 vos_ssr_protect(__func__);
4678 ret = __hdd_ioctl(dev, ifr, cmd);
4679 vos_ssr_unprotect(__func__);
4680
4681 return ret;
4682}
4683
Katya Nigame7b69a82015-04-28 15:24:06 +05304684int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4685{
4686 return 0;
4687}
4688
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004689#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004690/**---------------------------------------------------------------------------
4691
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004692 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004693
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004694 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004695 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4696 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4697 <space>Scan Mode N<space>Meas Duration N
4698 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4699 then take N.
4700 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4701 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4702 This function does not take care of removing duplicate channels from the list
4703
4704 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004705 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004706
4707 \return - 0 for success non-zero for failure
4708
4709 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004710static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4711 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004712{
4713 tANI_U8 *inPtr = pValue;
4714 int tempInt = 0;
4715 int j = 0, i = 0, v = 0;
4716 char buf[32];
4717
4718 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4719 /*no argument after the command*/
4720 if (NULL == inPtr)
4721 {
4722 return -EINVAL;
4723 }
4724 /*no space after the command*/
4725 else if (SPACE_ASCII_VALUE != *inPtr)
4726 {
4727 return -EINVAL;
4728 }
4729
4730 /*removing empty spaces*/
4731 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4732
4733 /*no argument followed by spaces*/
4734 if ('\0' == *inPtr) return -EINVAL;
4735
4736 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004737 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004738 if (1 != v) return -EINVAL;
4739
4740 v = kstrtos32(buf, 10, &tempInt);
4741 if ( v < 0) return -EINVAL;
4742
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004743 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004744
4745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004746 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004747
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004748 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004749 {
4750 for (i = 0; i < 4; i++)
4751 {
4752 /*inPtr pointing to the beginning of first space after number of ie fields*/
4753 inPtr = strpbrk( inPtr, " " );
4754 /*no ie data after the number of ie fields argument*/
4755 if (NULL == inPtr) return -EINVAL;
4756
4757 /*removing empty space*/
4758 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4759
4760 /*no ie data after the number of ie fields argument and spaces*/
4761 if ( '\0' == *inPtr ) return -EINVAL;
4762
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004763 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004764 if (1 != v) return -EINVAL;
4765
4766 v = kstrtos32(buf, 10, &tempInt);
4767 if (v < 0) return -EINVAL;
4768
4769 switch (i)
4770 {
4771 case 0: /* Measurement token */
4772 if (tempInt <= 0)
4773 {
4774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4775 "Invalid Measurement Token(%d)", tempInt);
4776 return -EINVAL;
4777 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004778 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004779 break;
4780
4781 case 1: /* Channel number */
4782 if ((tempInt <= 0) ||
4783 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4784 {
4785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4786 "Invalid Channel Number(%d)", tempInt);
4787 return -EINVAL;
4788 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004789 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004790 break;
4791
4792 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004793 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004794 {
4795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4796 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4797 return -EINVAL;
4798 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004799 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004800 break;
4801
4802 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004803 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4804 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004805 {
4806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4807 "Invalid Measurement Duration(%d)", tempInt);
4808 return -EINVAL;
4809 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004810 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004811 break;
4812 }
4813 }
4814 }
4815
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004816 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004817 {
4818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304819 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004820 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004821 pEseBcnReq->bcnReq[j].measurementToken,
4822 pEseBcnReq->bcnReq[j].channel,
4823 pEseBcnReq->bcnReq[j].scanMode,
4824 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004825 }
4826
4827 return VOS_STATUS_SUCCESS;
4828}
4829
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004830static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4831{
4832 struct statsContext *pStatsContext = NULL;
4833 hdd_adapter_t *pAdapter = NULL;
4834
4835 if (NULL == pContext)
4836 {
4837 hddLog(VOS_TRACE_LEVEL_ERROR,
4838 "%s: Bad param, pContext [%p]",
4839 __func__, pContext);
4840 return;
4841 }
4842
Jeff Johnson72a40512013-12-19 10:14:15 -08004843 /* there is a race condition that exists between this callback
4844 function and the caller since the caller could time out either
4845 before or while this code is executing. we use a spinlock to
4846 serialize these actions */
4847 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004848
4849 pStatsContext = pContext;
4850 pAdapter = pStatsContext->pAdapter;
4851 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4852 {
4853 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004854 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004855 hddLog(VOS_TRACE_LEVEL_WARN,
4856 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4857 __func__, pAdapter, pStatsContext->magic);
4858 return;
4859 }
4860
Jeff Johnson72a40512013-12-19 10:14:15 -08004861 /* context is valid so caller is still waiting */
4862
4863 /* paranoia: invalidate the magic */
4864 pStatsContext->magic = 0;
4865
4866 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004867 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4868 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4869 tsmMetrics.UplinkPktQueueDlyHist,
4870 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4871 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4872 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4873 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4874 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4875 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4876 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4877
Jeff Johnson72a40512013-12-19 10:14:15 -08004878 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004879 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004880
4881 /* serialization is complete */
4882 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004883}
4884
4885
4886
4887static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4888 tAniTrafStrmMetrics* pTsmMetrics)
4889{
4890 hdd_station_ctx_t *pHddStaCtx = NULL;
4891 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004892 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004893 long lrc;
4894 struct statsContext context;
4895 hdd_context_t *pHddCtx = NULL;
4896
4897 if (NULL == pAdapter)
4898 {
4899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4900 return VOS_STATUS_E_FAULT;
4901 }
4902
4903 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4904 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4905
4906 /* we are connected prepare our callback context */
4907 init_completion(&context.completion);
4908 context.pAdapter = pAdapter;
4909 context.magic = STATS_CONTEXT_MAGIC;
4910
4911 /* query tsm stats */
4912 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4913 pHddStaCtx->conn_info.staId[ 0 ],
4914 pHddStaCtx->conn_info.bssId,
4915 &context, pHddCtx->pvosContext, tid);
4916
4917 if (eHAL_STATUS_SUCCESS != hstatus)
4918 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4920 __func__);
4921 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004922 }
4923 else
4924 {
4925 /* request was sent -- wait for the response */
4926 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4927 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004928 if (lrc <= 0)
4929 {
4930 hddLog(VOS_TRACE_LEVEL_ERROR,
4931 "%s: SME %s while retrieving statistics",
4932 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004933 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004934 }
4935 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004936
Jeff Johnson72a40512013-12-19 10:14:15 -08004937 /* either we never sent a request, we sent a request and received a
4938 response or we sent a request and timed out. if we never sent a
4939 request or if we sent a request and got a response, we want to
4940 clear the magic out of paranoia. if we timed out there is a
4941 race condition such that the callback function could be
4942 executing at the same time we are. of primary concern is if the
4943 callback function had already verified the "magic" but had not
4944 yet set the completion variable when a timeout occurred. we
4945 serialize these activities by invalidating the magic while
4946 holding a shared spinlock which will cause us to block if the
4947 callback is currently executing */
4948 spin_lock(&hdd_context_lock);
4949 context.magic = 0;
4950 spin_unlock(&hdd_context_lock);
4951
4952 if (VOS_STATUS_SUCCESS == vstatus)
4953 {
4954 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4955 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4956 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4957 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4958 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4959 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4960 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4961 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4962 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4963 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4964 }
4965 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004966}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004967#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004968
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004969#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004970void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4971{
4972 eCsrBand band = -1;
4973 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4974 switch (band)
4975 {
4976 case eCSR_BAND_ALL:
4977 *pBand = WLAN_HDD_UI_BAND_AUTO;
4978 break;
4979
4980 case eCSR_BAND_24:
4981 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4982 break;
4983
4984 case eCSR_BAND_5G:
4985 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4986 break;
4987
4988 default:
4989 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4990 *pBand = -1;
4991 break;
4992 }
4993}
4994
4995/**---------------------------------------------------------------------------
4996
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004997 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4998
4999 This function parses the send action frame data passed in the format
5000 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
5001
Srinivas Girigowda56076852013-08-20 14:00:50 -07005002 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005003 \param - pTargetApBssid Pointer to target Ap bssid
5004 \param - pChannel Pointer to the Target AP channel
5005 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
5006 \param - pBuf Pointer to data
5007 \param - pBufLen Pointer to data length
5008
5009 \return - 0 for success non-zero for failure
5010
5011 --------------------------------------------------------------------------*/
5012VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
5013 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
5014{
5015 tANI_U8 *inPtr = pValue;
5016 tANI_U8 *dataEnd;
5017 int tempInt;
5018 int j = 0;
5019 int i = 0;
5020 int v = 0;
5021 tANI_U8 tempBuf[32];
5022 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005023 /* 12 hexa decimal digits, 5 ':' and '\0' */
5024 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005025
5026 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5027 /*no argument after the command*/
5028 if (NULL == inPtr)
5029 {
5030 return -EINVAL;
5031 }
5032
5033 /*no space after the command*/
5034 else if (SPACE_ASCII_VALUE != *inPtr)
5035 {
5036 return -EINVAL;
5037 }
5038
5039 /*removing empty spaces*/
5040 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5041
5042 /*no argument followed by spaces*/
5043 if ('\0' == *inPtr)
5044 {
5045 return -EINVAL;
5046 }
5047
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005048 v = sscanf(inPtr, "%17s", macAddress);
5049 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005050 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5052 "Invalid MAC address or All hex inputs are not read (%d)", v);
5053 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005054 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005055
5056 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5057 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5058 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5059 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5060 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5061 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005062
5063 /* point to the next argument */
5064 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5065 /*no argument after the command*/
5066 if (NULL == inPtr) return -EINVAL;
5067
5068 /*removing empty spaces*/
5069 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5070
5071 /*no argument followed by spaces*/
5072 if ('\0' == *inPtr)
5073 {
5074 return -EINVAL;
5075 }
5076
5077 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005078 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005079 if (1 != v) return -EINVAL;
5080
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005081 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305082 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305083 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005084
5085 *pChannel = tempInt;
5086
5087 /* point to the next argument */
5088 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5089 /*no argument after the command*/
5090 if (NULL == inPtr) return -EINVAL;
5091 /*removing empty spaces*/
5092 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5093
5094 /*no argument followed by spaces*/
5095 if ('\0' == *inPtr)
5096 {
5097 return -EINVAL;
5098 }
5099
5100 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005101 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005102 if (1 != v) return -EINVAL;
5103
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005104 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005105 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005106
5107 *pDwellTime = tempInt;
5108
5109 /* point to the next argument */
5110 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5111 /*no argument after the command*/
5112 if (NULL == inPtr) return -EINVAL;
5113 /*removing empty spaces*/
5114 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5115
5116 /*no argument followed by spaces*/
5117 if ('\0' == *inPtr)
5118 {
5119 return -EINVAL;
5120 }
5121
5122 /* find the length of data */
5123 dataEnd = inPtr;
5124 while(('\0' != *dataEnd) )
5125 {
5126 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005127 }
Kiet Lambe150c22013-11-21 16:30:32 +05305128 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005129 if ( *pBufLen <= 0) return -EINVAL;
5130
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005131 /* Allocate the number of bytes based on the number of input characters
5132 whether it is even or odd.
5133 if the number of input characters are even, then we need N/2 byte.
5134 if the number of input characters are odd, then we need do (N+1)/2 to
5135 compensate rounding off.
5136 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5137 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5138 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005139 if (NULL == *pBuf)
5140 {
5141 hddLog(VOS_TRACE_LEVEL_FATAL,
5142 "%s: vos_mem_alloc failed ", __func__);
5143 return -EINVAL;
5144 }
5145
5146 /* the buffer received from the upper layer is character buffer,
5147 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5148 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5149 and f0 in 3rd location */
5150 for (i = 0, j = 0; j < *pBufLen; j += 2)
5151 {
Kiet Lambe150c22013-11-21 16:30:32 +05305152 if( j+1 == *pBufLen)
5153 {
5154 tempByte = hdd_parse_hex(inPtr[j]);
5155 }
5156 else
5157 {
5158 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5159 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005160 (*pBuf)[i++] = tempByte;
5161 }
5162 *pBufLen = i;
5163 return VOS_STATUS_SUCCESS;
5164}
5165
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005166/**---------------------------------------------------------------------------
5167
Srinivas Girigowdade697412013-02-14 16:31:48 -08005168 \brief hdd_parse_channellist() - HDD Parse channel list
5169
5170 This function parses the channel list passed in the format
5171 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005172 if the Number of channels (N) does not match with the actual number of channels passed
5173 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5174 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5175 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5176 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005177
5178 \param - pValue Pointer to input channel list
5179 \param - ChannelList Pointer to local output array to record channel list
5180 \param - pNumChannels Pointer to number of roam scan channels
5181
5182 \return - 0 for success non-zero for failure
5183
5184 --------------------------------------------------------------------------*/
5185VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5186{
5187 tANI_U8 *inPtr = pValue;
5188 int tempInt;
5189 int j = 0;
5190 int v = 0;
5191 char buf[32];
5192
5193 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5194 /*no argument after the command*/
5195 if (NULL == inPtr)
5196 {
5197 return -EINVAL;
5198 }
5199
5200 /*no space after the command*/
5201 else if (SPACE_ASCII_VALUE != *inPtr)
5202 {
5203 return -EINVAL;
5204 }
5205
5206 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005207 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005208
5209 /*no argument followed by spaces*/
5210 if ('\0' == *inPtr)
5211 {
5212 return -EINVAL;
5213 }
5214
5215 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005216 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005217 if (1 != v) return -EINVAL;
5218
Srinivas Girigowdade697412013-02-14 16:31:48 -08005219 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005220 if ((v < 0) ||
5221 (tempInt <= 0) ||
5222 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5223 {
5224 return -EINVAL;
5225 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005226
5227 *pNumChannels = tempInt;
5228
5229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5230 "Number of channels are: %d", *pNumChannels);
5231
5232 for (j = 0; j < (*pNumChannels); j++)
5233 {
5234 /*inPtr pointing to the beginning of first space after number of channels*/
5235 inPtr = strpbrk( inPtr, " " );
5236 /*no channel list after the number of channels argument*/
5237 if (NULL == inPtr)
5238 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005239 if (0 != j)
5240 {
5241 *pNumChannels = j;
5242 return VOS_STATUS_SUCCESS;
5243 }
5244 else
5245 {
5246 return -EINVAL;
5247 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005248 }
5249
5250 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005251 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005252
5253 /*no channel list after the number of channels argument and spaces*/
5254 if ( '\0' == *inPtr )
5255 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005256 if (0 != j)
5257 {
5258 *pNumChannels = j;
5259 return VOS_STATUS_SUCCESS;
5260 }
5261 else
5262 {
5263 return -EINVAL;
5264 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005265 }
5266
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005267 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005268 if (1 != v) return -EINVAL;
5269
Srinivas Girigowdade697412013-02-14 16:31:48 -08005270 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005271 if ((v < 0) ||
5272 (tempInt <= 0) ||
5273 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5274 {
5275 return -EINVAL;
5276 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005277 pChannelList[j] = tempInt;
5278
5279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5280 "Channel %d added to preferred channel list",
5281 pChannelList[j] );
5282 }
5283
Srinivas Girigowdade697412013-02-14 16:31:48 -08005284 return VOS_STATUS_SUCCESS;
5285}
5286
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005287
5288/**---------------------------------------------------------------------------
5289
5290 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5291
5292 This function parses the reasoc command data passed in the format
5293 REASSOC<space><bssid><space><channel>
5294
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005295 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005296 \param - pTargetApBssid Pointer to target Ap bssid
5297 \param - pChannel Pointer to the Target AP channel
5298
5299 \return - 0 for success non-zero for failure
5300
5301 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005302VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5303 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005304{
5305 tANI_U8 *inPtr = pValue;
5306 int tempInt;
5307 int v = 0;
5308 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005309 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005310 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005311
5312 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5313 /*no argument after the command*/
5314 if (NULL == inPtr)
5315 {
5316 return -EINVAL;
5317 }
5318
5319 /*no space after the command*/
5320 else if (SPACE_ASCII_VALUE != *inPtr)
5321 {
5322 return -EINVAL;
5323 }
5324
5325 /*removing empty spaces*/
5326 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5327
5328 /*no argument followed by spaces*/
5329 if ('\0' == *inPtr)
5330 {
5331 return -EINVAL;
5332 }
5333
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005334 v = sscanf(inPtr, "%17s", macAddress);
5335 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005336 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5338 "Invalid MAC address or All hex inputs are not read (%d)", v);
5339 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005340 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005341
5342 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5343 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5344 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5345 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5346 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5347 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005348
5349 /* point to the next argument */
5350 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5351 /*no argument after the command*/
5352 if (NULL == inPtr) return -EINVAL;
5353
5354 /*removing empty spaces*/
5355 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5356
5357 /*no argument followed by spaces*/
5358 if ('\0' == *inPtr)
5359 {
5360 return -EINVAL;
5361 }
5362
5363 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005364 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005365 if (1 != v) return -EINVAL;
5366
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005367 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005368 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305369 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005370 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5371 {
5372 return -EINVAL;
5373 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005374
5375 *pChannel = tempInt;
5376 return VOS_STATUS_SUCCESS;
5377}
5378
5379#endif
5380
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005381#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005382/**---------------------------------------------------------------------------
5383
5384 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5385
5386 This function parses the SETCCKM IE command
5387 SETCCKMIE<space><ie data>
5388
5389 \param - pValue Pointer to input data
5390 \param - pCckmIe Pointer to output cckm Ie
5391 \param - pCckmIeLen Pointer to output cckm ie length
5392
5393 \return - 0 for success non-zero for failure
5394
5395 --------------------------------------------------------------------------*/
5396VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5397 tANI_U8 *pCckmIeLen)
5398{
5399 tANI_U8 *inPtr = pValue;
5400 tANI_U8 *dataEnd;
5401 int j = 0;
5402 int i = 0;
5403 tANI_U8 tempByte = 0;
5404
5405 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5406 /*no argument after the command*/
5407 if (NULL == inPtr)
5408 {
5409 return -EINVAL;
5410 }
5411
5412 /*no space after the command*/
5413 else if (SPACE_ASCII_VALUE != *inPtr)
5414 {
5415 return -EINVAL;
5416 }
5417
5418 /*removing empty spaces*/
5419 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5420
5421 /*no argument followed by spaces*/
5422 if ('\0' == *inPtr)
5423 {
5424 return -EINVAL;
5425 }
5426
5427 /* find the length of data */
5428 dataEnd = inPtr;
5429 while(('\0' != *dataEnd) )
5430 {
5431 dataEnd++;
5432 ++(*pCckmIeLen);
5433 }
5434 if ( *pCckmIeLen <= 0) return -EINVAL;
5435
5436 /* Allocate the number of bytes based on the number of input characters
5437 whether it is even or odd.
5438 if the number of input characters are even, then we need N/2 byte.
5439 if the number of input characters are odd, then we need do (N+1)/2 to
5440 compensate rounding off.
5441 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5442 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5443 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5444 if (NULL == *pCckmIe)
5445 {
5446 hddLog(VOS_TRACE_LEVEL_FATAL,
5447 "%s: vos_mem_alloc failed ", __func__);
5448 return -EINVAL;
5449 }
5450 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5451 /* the buffer received from the upper layer is character buffer,
5452 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5453 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5454 and f0 in 3rd location */
5455 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5456 {
5457 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5458 (*pCckmIe)[i++] = tempByte;
5459 }
5460 *pCckmIeLen = i;
5461
5462 return VOS_STATUS_SUCCESS;
5463}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005464#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466/**---------------------------------------------------------------------------
5467
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005468 \brief hdd_is_valid_mac_address() - Validate MAC address
5469
5470 This function validates whether the given MAC address is valid or not
5471 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5472 where X is the hexa decimal digit character and separated by ':'
5473 This algorithm works even if MAC address is not separated by ':'
5474
5475 This code checks given input string mac contains exactly 12 hexadecimal digits.
5476 and a separator colon : appears in the input string only after
5477 an even number of hex digits.
5478
5479 \param - pMacAddr pointer to the input MAC address
5480 \return - 1 for valid and 0 for invalid
5481
5482 --------------------------------------------------------------------------*/
5483
5484v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5485{
5486 int xdigit = 0;
5487 int separator = 0;
5488 while (*pMacAddr)
5489 {
5490 if (isxdigit(*pMacAddr))
5491 {
5492 xdigit++;
5493 }
5494 else if (':' == *pMacAddr)
5495 {
5496 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5497 break;
5498
5499 ++separator;
5500 }
5501 else
5502 {
5503 separator = -1;
5504 /* Invalid MAC found */
5505 return 0;
5506 }
5507 ++pMacAddr;
5508 }
5509 return (xdigit == 12 && (separator == 5 || separator == 0));
5510}
5511
5512/**---------------------------------------------------------------------------
5513
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305514 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005515
5516 \param - dev Pointer to net_device structure
5517
5518 \return - 0 for success non-zero for failure
5519
5520 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305521int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005522{
5523 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5524 hdd_context_t *pHddCtx;
5525 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5526 VOS_STATUS status;
5527 v_BOOL_t in_standby = TRUE;
5528
5529 if (NULL == pAdapter)
5530 {
5531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305532 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 return -ENODEV;
5534 }
5535
5536 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305537 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5538 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 if (NULL == pHddCtx)
5540 {
5541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005542 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 return -ENODEV;
5544 }
5545
5546 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5547 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5548 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005549 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5550 {
5551 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305552 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005553 in_standby = FALSE;
5554 break;
5555 }
5556 else
5557 {
5558 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5559 pAdapterNode = pNext;
5560 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 }
5562
5563 if (TRUE == in_standby)
5564 {
5565 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5566 {
5567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5568 "wlan out of power save", __func__);
5569 return -EINVAL;
5570 }
5571 }
5572
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005573 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5575 {
5576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005577 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 netif_tx_start_all_queues(dev);
5581 }
5582
5583 return 0;
5584}
5585
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305586/**---------------------------------------------------------------------------
5587
5588 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5589
5590 This is called in response to ifconfig up
5591
5592 \param - dev Pointer to net_device structure
5593
5594 \return - 0 for success non-zero for failure
5595
5596 --------------------------------------------------------------------------*/
5597int hdd_open(struct net_device *dev)
5598{
5599 int ret;
5600
5601 vos_ssr_protect(__func__);
5602 ret = __hdd_open(dev);
5603 vos_ssr_unprotect(__func__);
5604
5605 return ret;
5606}
5607
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305608int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005609{
5610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5611
5612 if(pAdapter == NULL) {
5613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005614 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005615 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 }
5617
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 return 0;
5619}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305620
5621int hdd_mon_open (struct net_device *dev)
5622{
5623 int ret;
5624
5625 vos_ssr_protect(__func__);
5626 ret = __hdd_mon_open(dev);
5627 vos_ssr_unprotect(__func__);
5628
5629 return ret;
5630}
5631
Katya Nigame7b69a82015-04-28 15:24:06 +05305632int hdd_mon_stop(struct net_device *dev)
5633{
5634 return 0;
5635}
5636
Jeff Johnson295189b2012-06-20 16:38:30 -07005637/**---------------------------------------------------------------------------
5638
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305639 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005640
5641 \param - dev Pointer to net_device structure
5642
5643 \return - 0 for success non-zero for failure
5644
5645 --------------------------------------------------------------------------*/
5646
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305647int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005648{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305649 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5651 hdd_context_t *pHddCtx;
5652 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5653 VOS_STATUS status;
5654 v_BOOL_t enter_standby = TRUE;
5655
5656 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 if (NULL == pAdapter)
5658 {
5659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305660 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005661 return -ENODEV;
5662 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305663 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305664 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305665
5666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5667 ret = wlan_hdd_validate_context(pHddCtx);
5668 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305670 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 }
5672
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305673 /* Nothing to be done if the interface is not opened */
5674 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5675 {
5676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5677 "%s: NETDEV Interface is not OPENED", __func__);
5678 return -ENODEV;
5679 }
5680
5681 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005682 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305684
5685 /* Disable TX on the interface, after this hard_start_xmit() will not
5686 * be called on that interface
5687 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305688 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305690
5691 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 netif_carrier_off(pAdapter->dev);
5693
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305694 /* The interface is marked as down for outside world (aka kernel)
5695 * But the driver is pretty much alive inside. The driver needs to
5696 * tear down the existing connection on the netdev (session)
5697 * cleanup the data pipes and wait until the control plane is stabilized
5698 * for this interface. The call also needs to wait until the above
5699 * mentioned actions are completed before returning to the caller.
5700 * Notice that the hdd_stop_adapter is requested not to close the session
5701 * That is intentional to be able to scan if it is a STA/P2P interface
5702 */
5703 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305704#ifdef FEATURE_WLAN_TDLS
5705 mutex_lock(&pHddCtx->tdls_lock);
5706#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305707 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305708 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305709#ifdef FEATURE_WLAN_TDLS
5710 mutex_unlock(&pHddCtx->tdls_lock);
5711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 /* SoftAP ifaces should never go in power save mode
5713 making sure same here. */
5714 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5715 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 )
5718 {
5719 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5721 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 EXIT();
5723 return 0;
5724 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305725 /* Find if any iface is up. If any iface is up then can't put device to
5726 * sleep/power save mode
5727 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5729 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5730 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005731 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5732 {
5733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305734 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005735 enter_standby = FALSE;
5736 break;
5737 }
5738 else
5739 {
5740 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5741 pAdapterNode = pNext;
5742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 }
5744
5745 if (TRUE == enter_standby)
5746 {
5747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5748 "entering standby", __func__);
5749 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5750 {
5751 /*log and return success*/
5752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5753 "wlan in power save", __func__);
5754 }
5755 }
5756
5757 EXIT();
5758 return 0;
5759}
5760
5761/**---------------------------------------------------------------------------
5762
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305763 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005764
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305765 This is called in response to ifconfig down
5766
5767 \param - dev Pointer to net_device structure
5768
5769 \return - 0 for success non-zero for failure
5770-----------------------------------------------------------------------------*/
5771int hdd_stop (struct net_device *dev)
5772{
5773 int ret;
5774
5775 vos_ssr_protect(__func__);
5776 ret = __hdd_stop(dev);
5777 vos_ssr_unprotect(__func__);
5778
5779 return ret;
5780}
5781
5782/**---------------------------------------------------------------------------
5783
5784 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005785
5786 \param - dev Pointer to net_device structure
5787
5788 \return - void
5789
5790 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305791static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005792{
5793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305794 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 ENTER();
5796
5797 do
5798 {
5799 if (NULL == pAdapter)
5800 {
5801 hddLog(VOS_TRACE_LEVEL_FATAL,
5802 "%s: NULL pAdapter", __func__);
5803 break;
5804 }
5805
5806 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5807 {
5808 hddLog(VOS_TRACE_LEVEL_FATAL,
5809 "%s: Invalid magic", __func__);
5810 break;
5811 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305812 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5813 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 {
5815 hddLog(VOS_TRACE_LEVEL_FATAL,
5816 "%s: NULL pHddCtx", __func__);
5817 break;
5818 }
5819
5820 if (dev != pAdapter->dev)
5821 {
5822 hddLog(VOS_TRACE_LEVEL_FATAL,
5823 "%s: Invalid device reference", __func__);
5824 /* we haven't validated all cases so let this go for now */
5825 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305826#ifdef FEATURE_WLAN_TDLS
5827 mutex_lock(&pHddCtx->tdls_lock);
5828#endif
c_hpothu002231a2015-02-05 14:58:51 +05305829 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305830#ifdef FEATURE_WLAN_TDLS
5831 mutex_unlock(&pHddCtx->tdls_lock);
5832#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005833
5834 /* after uninit our adapter structure will no longer be valid */
5835 pAdapter->dev = NULL;
5836 pAdapter->magic = 0;
5837 } while (0);
5838
5839 EXIT();
5840}
5841
5842/**---------------------------------------------------------------------------
5843
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305844 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5845
5846 This is called during the netdev unregister to uninitialize all data
5847associated with the device
5848
5849 \param - dev Pointer to net_device structure
5850
5851 \return - void
5852
5853 --------------------------------------------------------------------------*/
5854static void hdd_uninit (struct net_device *dev)
5855{
5856 vos_ssr_protect(__func__);
5857 __hdd_uninit(dev);
5858 vos_ssr_unprotect(__func__);
5859}
5860
5861/**---------------------------------------------------------------------------
5862
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 \brief hdd_release_firmware() -
5864
5865 This function calls the release firmware API to free the firmware buffer.
5866
5867 \param - pFileName Pointer to the File Name.
5868 pCtx - Pointer to the adapter .
5869
5870
5871 \return - 0 for success, non zero for failure
5872
5873 --------------------------------------------------------------------------*/
5874
5875VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5876{
5877 VOS_STATUS status = VOS_STATUS_SUCCESS;
5878 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5879 ENTER();
5880
5881
5882 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5883
5884 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5885
5886 if(pHddCtx->fw) {
5887 release_firmware(pHddCtx->fw);
5888 pHddCtx->fw = NULL;
5889 }
5890 else
5891 status = VOS_STATUS_E_FAILURE;
5892 }
5893 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5894 if(pHddCtx->nv) {
5895 release_firmware(pHddCtx->nv);
5896 pHddCtx->nv = NULL;
5897 }
5898 else
5899 status = VOS_STATUS_E_FAILURE;
5900
5901 }
5902
5903 EXIT();
5904 return status;
5905}
5906
5907/**---------------------------------------------------------------------------
5908
5909 \brief hdd_request_firmware() -
5910
5911 This function reads the firmware file using the request firmware
5912 API and returns the the firmware data and the firmware file size.
5913
5914 \param - pfileName - Pointer to the file name.
5915 - pCtx - Pointer to the adapter .
5916 - ppfw_data - Pointer to the pointer of the firmware data.
5917 - pSize - Pointer to the file size.
5918
5919 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5920
5921 --------------------------------------------------------------------------*/
5922
5923
5924VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5925{
5926 int status;
5927 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5928 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5929 ENTER();
5930
5931 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5932
5933 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5934
5935 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5936 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5937 __func__, pfileName);
5938 retval = VOS_STATUS_E_FAILURE;
5939 }
5940
5941 else {
5942 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5943 *pSize = pHddCtx->fw->size;
5944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5945 __func__, *pSize);
5946 }
5947 }
5948 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5949
5950 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5951
5952 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5953 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5954 __func__, pfileName);
5955 retval = VOS_STATUS_E_FAILURE;
5956 }
5957
5958 else {
5959 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5960 *pSize = pHddCtx->nv->size;
5961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5962 __func__, *pSize);
5963 }
5964 }
5965
5966 EXIT();
5967 return retval;
5968}
5969/**---------------------------------------------------------------------------
5970 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5971
5972 This is the function invoked by SME to inform the result of a full power
5973 request issued by HDD
5974
5975 \param - callbackcontext - Pointer to cookie
5976 status - result of request
5977
5978 \return - None
5979
5980--------------------------------------------------------------------------*/
5981void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5982{
5983 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5984
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005985 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 if(&pHddCtx->full_pwr_comp_var)
5987 {
5988 complete(&pHddCtx->full_pwr_comp_var);
5989 }
5990}
5991
5992/**---------------------------------------------------------------------------
5993
5994 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5995
5996 This is the function invoked by SME to inform the result of BMPS
5997 request issued by HDD
5998
5999 \param - callbackcontext - Pointer to cookie
6000 status - result of request
6001
6002 \return - None
6003
6004--------------------------------------------------------------------------*/
6005void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
6006{
6007
6008 struct completion *completion_var = (struct completion*) callbackContext;
6009
Arif Hussain6d2a3322013-11-17 19:50:10 -08006010 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 if(completion_var != NULL)
6012 {
6013 complete(completion_var);
6014 }
6015}
6016
6017/**---------------------------------------------------------------------------
6018
6019 \brief hdd_get_cfg_file_size() -
6020
6021 This function reads the configuration file using the request firmware
6022 API and returns the configuration file size.
6023
6024 \param - pCtx - Pointer to the adapter .
6025 - pFileName - Pointer to the file name.
6026 - pBufSize - Pointer to the buffer size.
6027
6028 \return - 0 for success, non zero for failure
6029
6030 --------------------------------------------------------------------------*/
6031
6032VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6033{
6034 int status;
6035 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6036
6037 ENTER();
6038
6039 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6040
6041 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6043 status = VOS_STATUS_E_FAILURE;
6044 }
6045 else {
6046 *pBufSize = pHddCtx->fw->size;
6047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6048 release_firmware(pHddCtx->fw);
6049 pHddCtx->fw = NULL;
6050 }
6051
6052 EXIT();
6053 return VOS_STATUS_SUCCESS;
6054}
6055
6056/**---------------------------------------------------------------------------
6057
6058 \brief hdd_read_cfg_file() -
6059
6060 This function reads the configuration file using the request firmware
6061 API and returns the cfg data and the buffer size of the configuration file.
6062
6063 \param - pCtx - Pointer to the adapter .
6064 - pFileName - Pointer to the file name.
6065 - pBuffer - Pointer to the data buffer.
6066 - pBufSize - Pointer to the buffer size.
6067
6068 \return - 0 for success, non zero for failure
6069
6070 --------------------------------------------------------------------------*/
6071
6072VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6073 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6074{
6075 int status;
6076 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6077
6078 ENTER();
6079
6080 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6081
6082 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6083 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6084 return VOS_STATUS_E_FAILURE;
6085 }
6086 else {
6087 if(*pBufSize != pHddCtx->fw->size) {
6088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6089 "file size", __func__);
6090 release_firmware(pHddCtx->fw);
6091 pHddCtx->fw = NULL;
6092 return VOS_STATUS_E_FAILURE;
6093 }
6094 else {
6095 if(pBuffer) {
6096 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6097 }
6098 release_firmware(pHddCtx->fw);
6099 pHddCtx->fw = NULL;
6100 }
6101 }
6102
6103 EXIT();
6104
6105 return VOS_STATUS_SUCCESS;
6106}
6107
6108/**---------------------------------------------------------------------------
6109
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306110 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006111
6112 This function sets the user specified mac address using
6113 the command ifconfig wlanX hw ether <mac adress>.
6114
6115 \param - dev - Pointer to the net device.
6116 - addr - Pointer to the sockaddr.
6117 \return - 0 for success, non zero for failure
6118
6119 --------------------------------------------------------------------------*/
6120
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306121static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006122{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306123 hdd_adapter_t *pAdapter;
6124 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 struct sockaddr *psta_mac_addr = addr;
6126 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306127 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006128
6129 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306130 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6131 if (NULL == pAdapter)
6132 {
6133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6134 "%s: Adapter is NULL",__func__);
6135 return -EINVAL;
6136 }
6137 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6138 ret = wlan_hdd_validate_context(pHddCtx);
6139 if (0 != ret)
6140 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306141 return ret;
6142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006143
6144 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6146
6147 EXIT();
6148 return halStatus;
6149}
6150
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306151/**---------------------------------------------------------------------------
6152
6153 \brief hdd_set_mac_address() -
6154
6155 Wrapper function to protect __hdd_set_mac_address() function from ssr
6156
6157 \param - dev - Pointer to the net device.
6158 - addr - Pointer to the sockaddr.
6159 \return - 0 for success, non zero for failure
6160
6161 --------------------------------------------------------------------------*/
6162static int hdd_set_mac_address(struct net_device *dev, void *addr)
6163{
6164 int ret;
6165
6166 vos_ssr_protect(__func__);
6167 ret = __hdd_set_mac_address(dev, addr);
6168 vos_ssr_unprotect(__func__);
6169
6170 return ret;
6171}
6172
Jeff Johnson295189b2012-06-20 16:38:30 -07006173tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6174{
6175 int i;
6176 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6177 {
Abhishek Singheb183782014-02-06 13:37:21 +05306178 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 break;
6180 }
6181
6182 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6183 return NULL;
6184
6185 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6186 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6187}
6188
6189void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6190{
6191 int i;
6192 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6193 {
6194 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6195 {
6196 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6197 break;
6198 }
6199 }
6200 return;
6201}
6202
6203#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6204 static struct net_device_ops wlan_drv_ops = {
6205 .ndo_open = hdd_open,
6206 .ndo_stop = hdd_stop,
6207 .ndo_uninit = hdd_uninit,
6208 .ndo_start_xmit = hdd_hard_start_xmit,
6209 .ndo_tx_timeout = hdd_tx_timeout,
6210 .ndo_get_stats = hdd_stats,
6211 .ndo_do_ioctl = hdd_ioctl,
6212 .ndo_set_mac_address = hdd_set_mac_address,
6213 .ndo_select_queue = hdd_select_queue,
6214#ifdef WLAN_FEATURE_PACKET_FILTERING
6215#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6216 .ndo_set_rx_mode = hdd_set_multicast_list,
6217#else
6218 .ndo_set_multicast_list = hdd_set_multicast_list,
6219#endif //LINUX_VERSION_CODE
6220#endif
6221 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 static struct net_device_ops wlan_mon_drv_ops = {
6223 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306224 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 .ndo_uninit = hdd_uninit,
6226 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6227 .ndo_tx_timeout = hdd_tx_timeout,
6228 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306229 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 .ndo_set_mac_address = hdd_set_mac_address,
6231 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306232
Jeff Johnson295189b2012-06-20 16:38:30 -07006233#endif
6234
6235void hdd_set_station_ops( struct net_device *pWlanDev )
6236{
6237#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 pWlanDev->netdev_ops = &wlan_drv_ops;
6239#else
6240 pWlanDev->open = hdd_open;
6241 pWlanDev->stop = hdd_stop;
6242 pWlanDev->uninit = hdd_uninit;
6243 pWlanDev->hard_start_xmit = NULL;
6244 pWlanDev->tx_timeout = hdd_tx_timeout;
6245 pWlanDev->get_stats = hdd_stats;
6246 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 pWlanDev->set_mac_address = hdd_set_mac_address;
6248#endif
6249}
6250
Katya Nigam1fd24402015-02-16 14:52:19 +05306251void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6252{
6253 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6254 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6255 #else
6256 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6257 #endif
6258}
6259
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006260static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006261{
6262 struct net_device *pWlanDev = NULL;
6263 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 /*
6265 * cfg80211 initialization and registration....
6266 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306267 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6268#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6269 NET_NAME_UNKNOWN,
6270#endif
6271 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 if(pWlanDev != NULL)
6273 {
6274
6275 //Save the pointer to the net_device in the HDD adapter
6276 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6277
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6279
6280 pAdapter->dev = pWlanDev;
6281 pAdapter->pHddCtx = pHddCtx;
6282 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306283 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006284
Rajeev79dbe4c2013-10-05 11:03:42 +05306285#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05306286 pAdapter->pBatchScanRsp = NULL;
6287 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006288 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006289 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306290 mutex_init(&pAdapter->hdd_batch_scan_lock);
6291#endif
6292
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 pAdapter->isLinkUpSvcNeeded = FALSE;
6294 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6295 //Init the net_device structure
6296 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6297
6298 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6299 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6300 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6301 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6302
6303 hdd_set_station_ops( pAdapter->dev );
6304
6305 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6307 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6308 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 /* set pWlanDev's parent to underlying device */
6310 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006311
6312 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 }
6314
6315 return pAdapter;
6316}
6317
6318VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6319{
6320 struct net_device *pWlanDev = pAdapter->dev;
6321 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6322 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6323 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6324
6325 if( rtnl_lock_held )
6326 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006327 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6329 {
6330 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6331 return VOS_STATUS_E_FAILURE;
6332 }
6333 }
6334 if (register_netdevice(pWlanDev))
6335 {
6336 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6337 return VOS_STATUS_E_FAILURE;
6338 }
6339 }
6340 else
6341 {
6342 if(register_netdev(pWlanDev))
6343 {
6344 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6345 return VOS_STATUS_E_FAILURE;
6346 }
6347 }
6348 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6349
6350 return VOS_STATUS_SUCCESS;
6351}
6352
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006353static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006354{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006355 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006356
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006357 if (NULL == pAdapter)
6358 {
6359 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6360 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006362
6363 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6364 {
6365 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6366 return eHAL_STATUS_NOT_INITIALIZED;
6367 }
6368
6369 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6370
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006371#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006372 /* need to make sure all of our scheduled work has completed.
6373 * This callback is called from MC thread context, so it is safe to
6374 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006375 *
6376 * Even though this is called from MC thread context, if there is a faulty
6377 * work item in the system, that can hang this call forever. So flushing
6378 * this global work queue is not safe; and now we make sure that
6379 * individual work queues are stopped correctly. But the cancel work queue
6380 * is a GPL only API, so the proprietary version of the driver would still
6381 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006382 */
6383 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006384#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006385
6386 /* We can be blocked while waiting for scheduled work to be
6387 * flushed, and the adapter structure can potentially be freed, in
6388 * which case the magic will have been reset. So make sure the
6389 * magic is still good, and hence the adapter structure is still
6390 * valid, before signaling completion */
6391 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6392 {
6393 complete(&pAdapter->session_close_comp_var);
6394 }
6395
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 return eHAL_STATUS_SUCCESS;
6397}
6398
6399VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6400{
6401 struct net_device *pWlanDev = pAdapter->dev;
6402 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6403 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6404 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6405 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306406 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006407
Nirav Shah7e3c8132015-06-22 23:51:42 +05306408 spin_lock_init( &pAdapter->sta_hash_lock);
6409 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6410
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006412 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 //Open a SME session for future operation
6414 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006415 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6417 {
6418 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006419 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 halStatus, halStatus );
6421 status = VOS_STATUS_E_FAILURE;
6422 goto error_sme_open;
6423 }
6424
6425 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306426 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 &pAdapter->session_open_comp_var,
6428 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306429 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
6431 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306432 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 status = VOS_STATUS_E_FAILURE;
6434 goto error_sme_open;
6435 }
6436
6437 // Register wireless extensions
6438 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6439 {
6440 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006441 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 halStatus, halStatus );
6443 status = VOS_STATUS_E_FAILURE;
6444 goto error_register_wext;
6445 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306446
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306448 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6449 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6450 #else
6451 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6452 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006453
6454 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306455 hddLog(VOS_TRACE_LEVEL_INFO,
6456 "%s: Set HDD connState to eConnectionState_NotConnected",
6457 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6459
6460 //Set the default operation channel
6461 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6462
6463 /* Make the default Auth Type as OPEN*/
6464 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6465
6466 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6467 {
6468 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006469 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 status, status );
6471 goto error_init_txrx;
6472 }
6473
6474 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6475
6476 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6477 {
6478 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006479 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 status, status );
6481 goto error_wmm_init;
6482 }
6483
6484 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6485
6486 return VOS_STATUS_SUCCESS;
6487
6488error_wmm_init:
6489 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6490 hdd_deinit_tx_rx(pAdapter);
6491error_init_txrx:
6492 hdd_UnregisterWext(pWlanDev);
6493error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006494 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 {
6496 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006497 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306498 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006499 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306501 unsigned long rc;
6502
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306504 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006506 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306507 if (rc <= 0)
6508 hddLog(VOS_TRACE_LEVEL_ERROR,
6509 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 }
6511}
6512error_sme_open:
6513 return status;
6514}
6515
Jeff Johnson295189b2012-06-20 16:38:30 -07006516void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6517{
6518 hdd_cfg80211_state_t *cfgState;
6519
6520 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6521
6522 if( NULL != cfgState->buf )
6523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306524 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6526 rc = wait_for_completion_interruptible_timeout(
6527 &pAdapter->tx_action_cnf_event,
6528 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306529 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6532 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6533 , __func__, rc);
6534
6535 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6536 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 }
6538 }
6539 return;
6540}
Jeff Johnson295189b2012-06-20 16:38:30 -07006541
c_hpothu002231a2015-02-05 14:58:51 +05306542void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006543{
6544 ENTER();
6545 switch ( pAdapter->device_mode )
6546 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306547 case WLAN_HDD_IBSS:
6548 {
6549 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6550 {
6551 hdd_ibss_deinit_tx_rx( pAdapter );
6552 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6553 }
6554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 case WLAN_HDD_INFRA_STATION:
6556 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006557 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 {
6559 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6560 {
6561 hdd_deinit_tx_rx( pAdapter );
6562 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6563 }
6564
6565 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6566 {
6567 hdd_wmm_adapter_close( pAdapter );
6568 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6569 }
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 break;
6573 }
6574
6575 case WLAN_HDD_SOFTAP:
6576 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306578
6579 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6580 {
6581 hdd_wmm_adapter_close( pAdapter );
6582 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6583 }
6584
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006586
c_hpothu002231a2015-02-05 14:58:51 +05306587 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 break;
6590 }
6591
6592 case WLAN_HDD_MONITOR:
6593 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6595 {
6596 hdd_deinit_tx_rx( pAdapter );
6597 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 break;
6600 }
6601
6602
6603 default:
6604 break;
6605 }
6606
6607 EXIT();
6608}
6609
6610void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6611{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006612 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306613
6614 ENTER();
6615 if (NULL == pAdapter)
6616 {
6617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6618 "%s: HDD adapter is Null", __func__);
6619 return;
6620 }
6621
6622 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006623
Rajeev79dbe4c2013-10-05 11:03:42 +05306624#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306625 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6626 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006627 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306628 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6629 )
6630 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006631 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306632 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006633 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6634 {
6635 hdd_deinit_batch_scan(pAdapter);
6636 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306637 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006638 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306639#endif
6640
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6642 if( rtnl_held )
6643 {
6644 unregister_netdevice(pWlanDev);
6645 }
6646 else
6647 {
6648 unregister_netdev(pWlanDev);
6649 }
6650 // note that the pAdapter is no longer valid at this point
6651 // since the memory has been reclaimed
6652 }
6653
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306654 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006655}
6656
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006657void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6658{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306659 VOS_STATUS status;
6660 hdd_adapter_t *pAdapter = NULL;
6661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006662
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306663 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006664
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306665 /*loop through all adapters.*/
6666 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006667 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306668 pAdapter = pAdapterNode->pAdapter;
6669 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6670 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006671
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306672 { // we skip this registration for modes other than STA and P2P client modes.
6673 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6674 pAdapterNode = pNext;
6675 continue;
6676 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006677
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306678 //Apply Dynamic DTIM For P2P
6679 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6680 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6681 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6682 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6683 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6684 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6685 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6686 (eConnectionState_Associated ==
6687 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6688 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6689 {
6690 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006691
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306692 powerRequest.uIgnoreDTIM = 1;
6693 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6694
6695 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6696 {
6697 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6698 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6699 }
6700 else
6701 {
6702 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6703 }
6704
6705 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6706 * specified during Enter/Exit BMPS when LCD off*/
6707 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6708 NULL, eANI_BOOLEAN_FALSE);
6709 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6710 NULL, eANI_BOOLEAN_FALSE);
6711
6712 /* switch to the DTIM specified in cfg.ini */
6713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05306714 "Switch to DTIM %d Listen interval %d",
6715 powerRequest.uDTIMPeriod,
6716 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306717 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6718 break;
6719
6720 }
6721
6722 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6723 pAdapterNode = pNext;
6724 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006725}
6726
6727void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6728{
6729 /*Switch back to DTIM 1*/
6730 tSirSetPowerParamsReq powerRequest = { 0 };
6731
6732 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6733 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006734 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006735
6736 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6737 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6738 NULL, eANI_BOOLEAN_FALSE);
6739 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6740 NULL, eANI_BOOLEAN_FALSE);
6741
6742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6743 "Switch to DTIM%d",powerRequest.uListenInterval);
6744 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6745
6746}
6747
Jeff Johnson295189b2012-06-20 16:38:30 -07006748VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6749{
6750 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306751 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6752 {
6753 hddLog( LOGE, FL("Wlan Unload in progress"));
6754 return VOS_STATUS_E_PERM;
6755 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6757 {
6758 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6759 }
6760
6761 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6762 {
6763 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6764 }
6765
6766 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6767 {
6768 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6769 }
6770
6771 return status;
6772}
6773
6774VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6775{
6776 hdd_adapter_t *pAdapter = NULL;
6777 eHalStatus halStatus;
6778 VOS_STATUS status = VOS_STATUS_E_INVAL;
6779 v_BOOL_t disableBmps = FALSE;
6780 v_BOOL_t disableImps = FALSE;
6781
6782 switch(session_type)
6783 {
6784 case WLAN_HDD_INFRA_STATION:
6785 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 case WLAN_HDD_P2P_CLIENT:
6787 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 //Exit BMPS -> Is Sta/P2P Client is already connected
6789 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6790 if((NULL != pAdapter)&&
6791 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6792 {
6793 disableBmps = TRUE;
6794 }
6795
6796 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6797 if((NULL != pAdapter)&&
6798 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6799 {
6800 disableBmps = TRUE;
6801 }
6802
6803 //Exit both Bmps and Imps incase of Go/SAP Mode
6804 if((WLAN_HDD_SOFTAP == session_type) ||
6805 (WLAN_HDD_P2P_GO == session_type))
6806 {
6807 disableBmps = TRUE;
6808 disableImps = TRUE;
6809 }
6810
6811 if(TRUE == disableImps)
6812 {
6813 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6814 {
6815 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6816 }
6817 }
6818
6819 if(TRUE == disableBmps)
6820 {
6821 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6822 {
6823 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6824
6825 if(eHAL_STATUS_SUCCESS != halStatus)
6826 {
6827 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006828 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 VOS_ASSERT(0);
6830 return status;
6831 }
6832 }
6833
6834 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6835 {
6836 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
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 Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 VOS_ASSERT(0);
6843 return status;
6844 }
6845 }
6846 }
6847
6848 if((TRUE == disableBmps) ||
6849 (TRUE == disableImps))
6850 {
6851 /* Now, get the chip into Full Power now */
6852 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6853 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6854 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6855
6856 if(halStatus != eHAL_STATUS_SUCCESS)
6857 {
6858 if(halStatus == eHAL_STATUS_PMC_PENDING)
6859 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306860 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306862 ret = wait_for_completion_interruptible_timeout(
6863 &pHddCtx->full_pwr_comp_var,
6864 msecs_to_jiffies(1000));
6865 if (ret <= 0)
6866 {
6867 hddLog(VOS_TRACE_LEVEL_ERROR,
6868 "%s: wait on full_pwr_comp_var failed %ld",
6869 __func__, ret);
6870 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 }
6872 else
6873 {
6874 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006875 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 VOS_ASSERT(0);
6877 return status;
6878 }
6879 }
6880
6881 status = VOS_STATUS_SUCCESS;
6882 }
6883
6884 break;
6885 }
6886 return status;
6887}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05306888
6889void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6890{
6891 if (magic == NULL || cmpVar == NULL) {
6892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6893 FL("invalid arguments %p %p"), magic, cmpVar);
6894 return;
6895 }
6896 if (*magic != MON_MODE_MSG_MAGIC) {
6897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6898 FL("maic: %x"), *magic);
6899 return;
6900 }
6901
6902 complete(cmpVar);
6903 return;
6904}
6905
Katya Nigame7b69a82015-04-28 15:24:06 +05306906void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6907 {
6908 hdd_mon_ctx_t *pMonCtx = NULL;
6909 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6910
6911 pMonCtx->state = 0;
6912 pMonCtx->ChannelNo = 1;
6913 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306914 pMonCtx->crcCheckEnabled = 1;
6915 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6916 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306917 pMonCtx->numOfMacFilters = 0;
6918 }
6919
Jeff Johnson295189b2012-06-20 16:38:30 -07006920
6921hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006922 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 tANI_U8 rtnl_held )
6924{
6925 hdd_adapter_t *pAdapter = NULL;
6926 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6927 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6928 VOS_STATUS exitbmpsStatus;
6929
Arif Hussain6d2a3322013-11-17 19:50:10 -08006930 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006931
Nirav Shah436658f2014-02-28 17:05:45 +05306932 if(macAddr == NULL)
6933 {
6934 /* Not received valid macAddr */
6935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6936 "%s:Unable to add virtual intf: Not able to get"
6937 "valid mac address",__func__);
6938 return NULL;
6939 }
6940
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 //Disable BMPS incase of Concurrency
6942 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6943
6944 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6945 {
6946 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306947 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 VOS_ASSERT(0);
6949 return NULL;
6950 }
6951
6952 switch(session_type)
6953 {
6954 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006956 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 {
6958 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6959
6960 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306961 {
6962 hddLog(VOS_TRACE_LEVEL_FATAL,
6963 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006966
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306967#ifdef FEATURE_WLAN_TDLS
6968 /* A Mutex Lock is introduced while changing/initializing the mode to
6969 * protect the concurrent access for the Adapters by TDLS module.
6970 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306971 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306972#endif
6973
Jeff Johnsone7245742012-09-05 17:12:55 -07006974 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6975 NL80211_IFTYPE_P2P_CLIENT:
6976 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006977
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306979#ifdef FEATURE_WLAN_TDLS
6980 mutex_unlock(&pHddCtx->tdls_lock);
6981#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306982
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05306983 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05306984 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 if( VOS_STATUS_SUCCESS != status )
6986 goto err_free_netdev;
6987
6988 status = hdd_register_interface( pAdapter, rtnl_held );
6989 if( VOS_STATUS_SUCCESS != status )
6990 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306991#ifdef FEATURE_WLAN_TDLS
6992 mutex_lock(&pHddCtx->tdls_lock);
6993#endif
c_hpothu002231a2015-02-05 14:58:51 +05306994 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306995#ifdef FEATURE_WLAN_TDLS
6996 mutex_unlock(&pHddCtx->tdls_lock);
6997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 goto err_free_netdev;
6999 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307000
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307001 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307002 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307003
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307004#ifdef WLAN_NS_OFFLOAD
7005 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307006 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307009 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007010 netif_tx_disable(pAdapter->dev);
7011 //netif_tx_disable(pWlanDev);
7012 netif_carrier_off(pAdapter->dev);
7013
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307014 if (WLAN_HDD_P2P_CLIENT == session_type ||
7015 WLAN_HDD_P2P_DEVICE == session_type)
7016 {
7017 /* Initialize the work queue to defer the
7018 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307019 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307020 hdd_p2p_roc_work_queue);
7021 }
7022
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 break;
7024 }
7025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 case WLAN_HDD_SOFTAP:
7028 {
7029 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7030 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307031 {
7032 hddLog(VOS_TRACE_LEVEL_FATAL,
7033 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007036
Jeff Johnson295189b2012-06-20 16:38:30 -07007037 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7038 NL80211_IFTYPE_AP:
7039 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 pAdapter->device_mode = session_type;
7041
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307042 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 status = hdd_init_ap_mode(pAdapter);
7044 if( VOS_STATUS_SUCCESS != status )
7045 goto err_free_netdev;
7046
Nirav Shah7e3c8132015-06-22 23:51:42 +05307047 status = hdd_sta_id_hash_attach(pAdapter);
7048 if (VOS_STATUS_SUCCESS != status)
7049 {
7050 hddLog(VOS_TRACE_LEVEL_FATAL,
7051 FL("failed to attach hash for session %d"), session_type);
7052 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7053 goto err_free_netdev;
7054 }
7055
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 status = hdd_register_hostapd( pAdapter, rtnl_held );
7057 if( VOS_STATUS_SUCCESS != status )
7058 {
c_hpothu002231a2015-02-05 14:58:51 +05307059 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 goto err_free_netdev;
7061 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307062 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 netif_tx_disable(pAdapter->dev);
7064 netif_carrier_off(pAdapter->dev);
7065
7066 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307067
7068 if (WLAN_HDD_P2P_GO == session_type)
7069 {
7070 /* Initialize the work queue to
7071 * defer the back to back RoC request */
7072 INIT_DELAYED_WORK(&pAdapter->roc_work,
7073 hdd_p2p_roc_work_queue);
7074 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 break;
7076 }
7077 case WLAN_HDD_MONITOR:
7078 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7080 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307081 {
7082 hddLog(VOS_TRACE_LEVEL_FATAL,
7083 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007086
Katya Nigame7b69a82015-04-28 15:24:06 +05307087 // Register wireless extensions
7088 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7089 {
7090 hddLog(VOS_TRACE_LEVEL_FATAL,
7091 "hdd_register_wext() failed with status code %08d [x%08x]",
7092 status, status );
7093 status = VOS_STATUS_E_FAILURE;
7094 }
7095
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7097 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007098#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7099 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7100#else
7101 pAdapter->dev->open = hdd_mon_open;
7102 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307103 pAdapter->dev->stop = hdd_mon_stop;
7104 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007105#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307106 status = hdd_register_interface( pAdapter, rtnl_held );
7107 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307108 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 hdd_init_tx_rx( pAdapter );
7110 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307111 //Stop the Interface TX queue.
7112 netif_tx_disable(pAdapter->dev);
7113 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 }
7115 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 case WLAN_HDD_FTM:
7117 {
7118 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7119
7120 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307121 {
7122 hddLog(VOS_TRACE_LEVEL_FATAL,
7123 FL("failed to allocate adapter for session %d"), session_type);
7124 return NULL;
7125 }
7126
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7128 * message while loading driver in FTM mode. */
7129 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7130 pAdapter->device_mode = session_type;
7131 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307132
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307133 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307134 hdd_init_tx_rx( pAdapter );
7135
7136 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307137 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307138 netif_tx_disable(pAdapter->dev);
7139 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 }
7141 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 default:
7143 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307144 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7145 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 VOS_ASSERT(0);
7147 return NULL;
7148 }
7149 }
7150
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 if( VOS_STATUS_SUCCESS == status )
7152 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307153 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7155 if( NULL == pHddAdapterNode )
7156 {
7157 status = VOS_STATUS_E_NOMEM;
7158 }
7159 else
7160 {
7161 pHddAdapterNode->pAdapter = pAdapter;
7162 status = hdd_add_adapter_back ( pHddCtx,
7163 pHddAdapterNode );
7164 }
7165 }
7166
7167 if( VOS_STATUS_SUCCESS != status )
7168 {
7169 if( NULL != pAdapter )
7170 {
7171 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7172 pAdapter = NULL;
7173 }
7174 if( NULL != pHddAdapterNode )
7175 {
7176 vos_mem_free( pHddAdapterNode );
7177 }
7178
7179 goto resume_bmps;
7180 }
7181
7182 if(VOS_STATUS_SUCCESS == status)
7183 {
7184 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7185
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007186 //Initialize the WoWL service
7187 if(!hdd_init_wowl(pAdapter))
7188 {
7189 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7190 goto err_free_netdev;
7191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 return pAdapter;
7194
7195err_free_netdev:
7196 free_netdev(pAdapter->dev);
7197 wlan_hdd_release_intf_addr( pHddCtx,
7198 pAdapter->macAddressCurrent.bytes );
7199
7200resume_bmps:
7201 //If bmps disabled enable it
7202 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7203 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307204 if (pHddCtx->hdd_wlan_suspended)
7205 {
7206 hdd_set_pwrparams(pHddCtx);
7207 }
7208 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007209 }
7210 return NULL;
7211}
7212
7213VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7214 tANI_U8 rtnl_held )
7215{
7216 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7217 VOS_STATUS status;
7218
7219 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7220 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307221 {
7222 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7223 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307225 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007226
7227 while ( pCurrent->pAdapter != pAdapter )
7228 {
7229 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7230 if( VOS_STATUS_SUCCESS != status )
7231 break;
7232
7233 pCurrent = pNext;
7234 }
7235 pAdapterNode = pCurrent;
7236 if( VOS_STATUS_SUCCESS == status )
7237 {
7238 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7239 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307240
7241#ifdef FEATURE_WLAN_TDLS
7242
7243 /* A Mutex Lock is introduced while changing/initializing the mode to
7244 * protect the concurrent access for the Adapters by TDLS module.
7245 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307246 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307247#endif
7248
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 hdd_remove_adapter( pHddCtx, pAdapterNode );
7250 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007251 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007252
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307253#ifdef FEATURE_WLAN_TDLS
7254 mutex_unlock(&pHddCtx->tdls_lock);
7255#endif
7256
Jeff Johnson295189b2012-06-20 16:38:30 -07007257
7258 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307259 if ((!vos_concurrent_open_sessions_running()) &&
7260 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7261 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307263 if (pHddCtx->hdd_wlan_suspended)
7264 {
7265 hdd_set_pwrparams(pHddCtx);
7266 }
7267 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 }
7269
7270 return VOS_STATUS_SUCCESS;
7271 }
7272
7273 return VOS_STATUS_E_FAILURE;
7274}
7275
7276VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7277{
7278 hdd_adapter_list_node_t *pHddAdapterNode;
7279 VOS_STATUS status;
7280
7281 ENTER();
7282
7283 do
7284 {
7285 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7286 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7287 {
7288 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7289 vos_mem_free( pHddAdapterNode );
7290 }
7291 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7292
7293 EXIT();
7294
7295 return VOS_STATUS_SUCCESS;
7296}
7297
7298void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7299{
7300 v_U8_t addIE[1] = {0};
7301
7302 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7303 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7304 eANI_BOOLEAN_FALSE) )
7305 {
7306 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007307 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 }
7309
7310 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7311 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7312 eANI_BOOLEAN_FALSE) )
7313 {
7314 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007315 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007316 }
7317
7318 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7319 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7320 eANI_BOOLEAN_FALSE) )
7321 {
7322 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007323 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 }
7325}
7326
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307327VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7328 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007329{
7330 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7331 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307332 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307334 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307335 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307336 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007337
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307338 if (pHddCtx->isLogpInProgress) {
7339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7340 "%s:LOGP in Progress. Ignore!!!",__func__);
7341 return VOS_STATUS_E_FAILURE;
7342 }
7343
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307345
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307346 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 switch(pAdapter->device_mode)
7348 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05307349 case WLAN_HDD_IBSS:
7350 if ( VOS_TRUE == bCloseSession )
7351 {
7352 status = hdd_sta_id_hash_detach(pAdapter);
7353 if (status != VOS_STATUS_SUCCESS)
7354 hddLog(VOS_TRACE_LEVEL_ERROR,
7355 FL("sta id hash detach failed"));
7356 }
7357
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 case WLAN_HDD_INFRA_STATION:
7359 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007360 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307361 {
7362 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307363#ifdef FEATURE_WLAN_TDLS
7364 mutex_lock(&pHddCtx->tdls_lock);
7365 wlan_hdd_tdls_exit(pAdapter, TRUE);
7366 mutex_unlock(&pHddCtx->tdls_lock);
7367#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307368 if( hdd_connIsConnected(pstation) ||
7369 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 {
7371 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7372 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7373 pAdapter->sessionId,
7374 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7375 else
7376 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7377 pAdapter->sessionId,
7378 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7379 //success implies disconnect command got queued up successfully
7380 if(halStatus == eHAL_STATUS_SUCCESS)
7381 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307382 ret = wait_for_completion_interruptible_timeout(
7383 &pAdapter->disconnect_comp_var,
7384 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7385 if (ret <= 0)
7386 {
7387 hddLog(VOS_TRACE_LEVEL_ERROR,
7388 "%s: wait on disconnect_comp_var failed %ld",
7389 __func__, ret);
7390 }
7391 }
7392 else
7393 {
7394 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7395 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 }
7397 memset(&wrqu, '\0', sizeof(wrqu));
7398 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7399 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7400 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7401 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307402 else if(pstation->conn_info.connState ==
7403 eConnectionState_Disconnecting)
7404 {
7405 ret = wait_for_completion_interruptible_timeout(
7406 &pAdapter->disconnect_comp_var,
7407 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7408 if (ret <= 0)
7409 {
7410 hddLog(VOS_TRACE_LEVEL_ERROR,
7411 FL("wait on disconnect_comp_var failed %ld"), ret);
7412 }
7413 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307414 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307416 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307417 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307419 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7420 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307421 {
7422 while (pAdapter->is_roc_inprogress)
7423 {
7424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7425 "%s: ROC in progress for session %d!!!",
7426 __func__, pAdapter->sessionId);
7427 // waiting for ROC to expire
7428 msleep(500);
7429 /* In GO present case , if retry exceeds 3,
7430 it means something went wrong. */
7431 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7432 {
7433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7434 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307435 if (eHAL_STATUS_SUCCESS !=
7436 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7437 pAdapter->sessionId ))
7438 {
7439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7440 FL("Failed to Cancel Remain on Channel"));
7441 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307442 wait_for_completion_interruptible_timeout(
7443 &pAdapter->cancel_rem_on_chan_var,
7444 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7445 break;
7446 }
7447 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307448 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307449 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307450#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307451 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307452#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307453
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307454 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307455
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307456 /* It is possible that the caller of this function does not
7457 * wish to close the session
7458 */
7459 if (VOS_TRUE == bCloseSession &&
7460 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 {
7462 INIT_COMPLETION(pAdapter->session_close_comp_var);
7463 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307464 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307465 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307467 unsigned long ret;
7468
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307470 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307471 &pAdapter->session_close_comp_var,
7472 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307473 if ( 0 >= ret)
7474 {
7475 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307476 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 }
7479 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 break;
7482
7483 case WLAN_HDD_SOFTAP:
7484 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05307485 if ( VOS_TRUE == bCloseSession )
7486 {
7487 status = hdd_sta_id_hash_detach(pAdapter);
7488 if (status != VOS_STATUS_SUCCESS)
7489 hddLog(VOS_TRACE_LEVEL_ERROR,
7490 FL("sta id hash detach failed"));
7491 }
7492
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307494 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7495 while (pAdapter->is_roc_inprogress) {
7496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7497 "%s: ROC in progress for session %d!!!",
7498 __func__, pAdapter->sessionId);
7499 msleep(500);
7500 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7502 "%s: ROC completion is not received.!!!", __func__);
7503 WLANSAP_CancelRemainOnChannel(
7504 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7505 wait_for_completion_interruptible_timeout(
7506 &pAdapter->cancel_rem_on_chan_var,
7507 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7508 break;
7509 }
7510 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307511
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307512 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 mutex_lock(&pHddCtx->sap_lock);
7515 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7516 {
7517 VOS_STATUS status;
7518 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7519
7520 //Stop Bss.
7521 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7522 if (VOS_IS_STATUS_SUCCESS(status))
7523 {
7524 hdd_hostapd_state_t *pHostapdState =
7525 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7526
7527 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7528
7529 if (!VOS_IS_STATUS_SUCCESS(status))
7530 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307531 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7532 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007533 }
7534 }
7535 else
7536 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007537 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 }
7539 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307540 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007541
7542 if (eHAL_STATUS_FAILURE ==
7543 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7544 0, NULL, eANI_BOOLEAN_FALSE))
7545 {
7546 hddLog(LOGE,
7547 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007548 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 }
7550
7551 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7552 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7553 eANI_BOOLEAN_FALSE) )
7554 {
7555 hddLog(LOGE,
7556 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7557 }
7558
7559 // Reset WNI_CFG_PROBE_RSP Flags
7560 wlan_hdd_reset_prob_rspies(pAdapter);
7561 kfree(pAdapter->sessionCtx.ap.beacon);
7562 pAdapter->sessionCtx.ap.beacon = NULL;
7563 }
7564 mutex_unlock(&pHddCtx->sap_lock);
7565 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007566
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 case WLAN_HDD_MONITOR:
7568 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007569
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 default:
7571 break;
7572 }
7573
7574 EXIT();
7575 return VOS_STATUS_SUCCESS;
7576}
7577
7578VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7579{
7580 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7581 VOS_STATUS status;
7582 hdd_adapter_t *pAdapter;
7583
7584 ENTER();
7585
7586 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7587
7588 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7589 {
7590 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007591
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307592 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007593
7594 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7595 pAdapterNode = pNext;
7596 }
7597
7598 EXIT();
7599
7600 return VOS_STATUS_SUCCESS;
7601}
7602
Rajeev Kumarf999e582014-01-09 17:33:29 -08007603
7604#ifdef FEATURE_WLAN_BATCH_SCAN
7605/**---------------------------------------------------------------------------
7606
7607 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7608 structures
7609
7610 \param - pAdapter Pointer to HDD adapter
7611
7612 \return - None
7613
7614 --------------------------------------------------------------------------*/
7615void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7616{
7617 tHddBatchScanRsp *pNode;
7618 tHddBatchScanRsp *pPrev;
7619
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307620 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007621 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307622 hddLog(VOS_TRACE_LEVEL_ERROR,
7623 "%s: Adapter context is Null", __func__);
7624 return;
7625 }
7626
7627 pNode = pAdapter->pBatchScanRsp;
7628 while (pNode)
7629 {
7630 pPrev = pNode;
7631 pNode = pNode->pNext;
7632 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007633 }
7634
7635 pAdapter->pBatchScanRsp = NULL;
7636 pAdapter->numScanList = 0;
7637 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7638 pAdapter->prev_batch_id = 0;
7639
7640 return;
7641}
7642#endif
7643
7644
Jeff Johnson295189b2012-06-20 16:38:30 -07007645VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7646{
7647 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7648 VOS_STATUS status;
7649 hdd_adapter_t *pAdapter;
7650
7651 ENTER();
7652
7653 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7654
7655 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7656 {
7657 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307658 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 netif_tx_disable(pAdapter->dev);
7660 netif_carrier_off(pAdapter->dev);
7661
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007662 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7663
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307665
Katya Nigam1fd24402015-02-16 14:52:19 +05307666 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7667 hdd_ibss_deinit_tx_rx(pAdapter);
7668
Nirav Shah7e3c8132015-06-22 23:51:42 +05307669 status = hdd_sta_id_hash_detach(pAdapter);
7670 if (status != VOS_STATUS_SUCCESS)
7671 hddLog(VOS_TRACE_LEVEL_ERROR,
7672 FL("sta id hash detach failed for session id %d"),
7673 pAdapter->sessionId);
7674
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307675 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7676
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307677 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7678 {
7679 hdd_wmm_adapter_close( pAdapter );
7680 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007682
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307683 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7684 {
7685 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7686 }
7687
Rajeev Kumarf999e582014-01-09 17:33:29 -08007688#ifdef FEATURE_WLAN_BATCH_SCAN
7689 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7690 {
7691 hdd_deinit_batch_scan(pAdapter);
7692 }
7693#endif
7694
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307695#ifdef FEATURE_WLAN_TDLS
7696 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307697 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307698 mutex_unlock(&pHddCtx->tdls_lock);
7699#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7701 pAdapterNode = pNext;
7702 }
7703
7704 EXIT();
7705
7706 return VOS_STATUS_SUCCESS;
7707}
7708
7709VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7710{
7711 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7712 VOS_STATUS status;
7713 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307714 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007715
7716 ENTER();
7717
7718 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7719
7720 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7721 {
7722 pAdapter = pAdapterNode->pAdapter;
7723
Kumar Anand82c009f2014-05-29 00:29:42 -07007724 hdd_wmm_init( pAdapter );
7725
Jeff Johnson295189b2012-06-20 16:38:30 -07007726 switch(pAdapter->device_mode)
7727 {
7728 case WLAN_HDD_INFRA_STATION:
7729 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007730 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307731
7732 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7733
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 hdd_init_station_mode(pAdapter);
7735 /* Open the gates for HDD to receive Wext commands */
7736 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007737 pHddCtx->scan_info.mScanPending = FALSE;
7738 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007739
7740 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307741 if (!pHddCtx->isLogpInProgress)
7742 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007743
7744 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307745 if (eConnectionState_Associated == connState ||
7746 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 {
7748 union iwreq_data wrqu;
7749 memset(&wrqu, '\0', sizeof(wrqu));
7750 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7751 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7752 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007753 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007754
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 /* indicate disconnected event to nl80211 */
7756 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7757 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307759 else if (eConnectionState_Connecting == connState)
7760 {
7761 /*
7762 * Indicate connect failure to supplicant if we were in the
7763 * process of connecting
7764 */
7765 cfg80211_connect_result(pAdapter->dev, NULL,
7766 NULL, 0, NULL, 0,
7767 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7768 GFP_KERNEL);
7769 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 break;
7771
7772 case WLAN_HDD_SOFTAP:
7773 /* softAP can handle SSR */
7774 break;
7775
7776 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007778 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007779 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 break;
7781
7782 case WLAN_HDD_MONITOR:
7783 /* monitor interface start */
7784 break;
7785 default:
7786 break;
7787 }
7788
7789 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7790 pAdapterNode = pNext;
7791 }
7792
7793 EXIT();
7794
7795 return VOS_STATUS_SUCCESS;
7796}
7797
7798VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7799{
7800 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7801 hdd_adapter_t *pAdapter;
7802 VOS_STATUS status;
7803 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307804 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007805
7806 ENTER();
7807
7808 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7809
7810 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7811 {
7812 pAdapter = pAdapterNode->pAdapter;
7813
7814 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7815 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7816 {
7817 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7818 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7819
Abhishek Singhf4669da2014-05-26 15:07:49 +05307820 hddLog(VOS_TRACE_LEVEL_INFO,
7821 "%s: Set HDD connState to eConnectionState_NotConnected",
7822 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307823 spin_lock_bh(&pAdapter->lock_for_active_session);
7824 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7825 {
7826 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7827 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307829 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 init_completion(&pAdapter->disconnect_comp_var);
7831 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7832 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7833
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307834 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 &pAdapter->disconnect_comp_var,
7836 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307837 if (0 >= ret)
7838 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7839 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007840
7841 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7842 pHddCtx->isAmpAllowed = VOS_FALSE;
7843 sme_RoamConnect(pHddCtx->hHal,
7844 pAdapter->sessionId, &(pWextState->roamProfile),
7845 &roamId);
7846 }
7847
7848 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7849 pAdapterNode = pNext;
7850 }
7851
7852 EXIT();
7853
7854 return VOS_STATUS_SUCCESS;
7855}
7856
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007857void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7858{
7859 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7860 VOS_STATUS status;
7861 hdd_adapter_t *pAdapter;
7862 hdd_station_ctx_t *pHddStaCtx;
7863 hdd_ap_ctx_t *pHddApCtx;
7864 hdd_hostapd_state_t * pHostapdState;
7865 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7866 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7867 const char *p2pMode = "DEV";
7868 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007869
7870 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7871 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7872 {
7873 pAdapter = pAdapterNode->pAdapter;
7874 switch (pAdapter->device_mode) {
7875 case WLAN_HDD_INFRA_STATION:
7876 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7877 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7878 staChannel = pHddStaCtx->conn_info.operationChannel;
7879 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7880 }
7881 break;
7882 case WLAN_HDD_P2P_CLIENT:
7883 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7884 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7885 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7886 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7887 p2pMode = "CLI";
7888 }
7889 break;
7890 case WLAN_HDD_P2P_GO:
7891 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7892 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7893 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7894 p2pChannel = pHddApCtx->operatingChannel;
7895 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7896 }
7897 p2pMode = "GO";
7898 break;
7899 case WLAN_HDD_SOFTAP:
7900 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7901 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7902 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7903 apChannel = pHddApCtx->operatingChannel;
7904 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7905 }
7906 break;
7907 default:
7908 break;
7909 }
7910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7911 pAdapterNode = pNext;
7912 }
7913 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7914 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7915 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307916 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007917 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7918 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307919 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007920 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7921 }
7922 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307923 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007924 apChannel, MAC_ADDR_ARRAY(apBssid));
7925 }
7926
7927 if (p2pChannel > 0 && apChannel > 0) {
7928 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7929 }
7930}
7931
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007932bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007933{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007934 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007935}
7936
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007937/* Once SSR is disabled then it cannot be set. */
7938void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007939{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007940 if (HDD_SSR_DISABLED == isSsrRequired)
7941 return;
7942
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 isSsrRequired = value;
7944}
7945
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307946void hdd_set_pre_close( hdd_context_t *pHddCtx)
7947{
7948 sme_PreClose(pHddCtx->hHal);
7949}
7950
Jeff Johnson295189b2012-06-20 16:38:30 -07007951VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7952 hdd_adapter_list_node_t** ppAdapterNode)
7953{
7954 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307955 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7957 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307958 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 return status;
7960}
7961
7962VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7963 hdd_adapter_list_node_t* pAdapterNode,
7964 hdd_adapter_list_node_t** pNextAdapterNode)
7965{
7966 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307967 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7969 (hdd_list_node_t*) pAdapterNode,
7970 (hdd_list_node_t**)pNextAdapterNode );
7971
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_remove_adapter( hdd_context_t *pHddCtx,
7977 hdd_adapter_list_node_t* pAdapterNode)
7978{
7979 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307980 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007981 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7982 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307983 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 return status;
7985}
7986
7987VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7988 hdd_adapter_list_node_t** ppAdapterNode)
7989{
7990 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307991 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7993 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307994 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007995 return status;
7996}
7997
7998VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7999 hdd_adapter_list_node_t* pAdapterNode)
8000{
8001 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308002 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
8004 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308005 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 return status;
8007}
8008
8009VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
8010 hdd_adapter_list_node_t* pAdapterNode)
8011{
8012 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308013 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8015 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308016 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 return status;
8018}
8019
8020hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8021 tSirMacAddr macAddr )
8022{
8023 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8024 hdd_adapter_t *pAdapter;
8025 VOS_STATUS status;
8026
8027 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8028
8029 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8030 {
8031 pAdapter = pAdapterNode->pAdapter;
8032
8033 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8034 macAddr, sizeof(tSirMacAddr) ) )
8035 {
8036 return pAdapter;
8037 }
8038 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8039 pAdapterNode = pNext;
8040 }
8041
8042 return NULL;
8043
8044}
8045
8046hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8047{
8048 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8049 hdd_adapter_t *pAdapter;
8050 VOS_STATUS status;
8051
8052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8053
8054 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8055 {
8056 pAdapter = pAdapterNode->pAdapter;
8057
8058 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8059 IFNAMSIZ ) )
8060 {
8061 return pAdapter;
8062 }
8063 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8064 pAdapterNode = pNext;
8065 }
8066
8067 return NULL;
8068
8069}
8070
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05308071hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8072 tANI_U32 sme_session_id )
8073{
8074 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8075 hdd_adapter_t *pAdapter;
8076 VOS_STATUS vos_status;
8077
8078
8079 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8080
8081 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8082 {
8083 pAdapter = pAdapterNode->pAdapter;
8084
8085 if (pAdapter->sessionId == sme_session_id)
8086 return pAdapter;
8087
8088 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8089 pAdapterNode = pNext;
8090 }
8091
8092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8093 "%s: sme_session_id %d does not exist with host",
8094 __func__, sme_session_id);
8095
8096 return NULL;
8097}
8098
Jeff Johnson295189b2012-06-20 16:38:30 -07008099hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8100{
8101 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8102 hdd_adapter_t *pAdapter;
8103 VOS_STATUS status;
8104
8105 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8106
8107 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8108 {
8109 pAdapter = pAdapterNode->pAdapter;
8110
8111 if( pAdapter && (mode == pAdapter->device_mode) )
8112 {
8113 return pAdapter;
8114 }
8115 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8116 pAdapterNode = pNext;
8117 }
8118
8119 return NULL;
8120
8121}
8122
8123//Remove this function later
8124hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8125{
8126 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8127 hdd_adapter_t *pAdapter;
8128 VOS_STATUS status;
8129
8130 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8131
8132 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8133 {
8134 pAdapter = pAdapterNode->pAdapter;
8135
8136 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8137 {
8138 return pAdapter;
8139 }
8140
8141 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8142 pAdapterNode = pNext;
8143 }
8144
8145 return NULL;
8146
8147}
8148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149/**---------------------------------------------------------------------------
8150
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308151 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008152
8153 This API returns the operating channel of the requested device mode
8154
8155 \param - pHddCtx - Pointer to the HDD context.
8156 - mode - Device mode for which operating channel is required
8157 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8158 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8159 \return - channel number. "0" id the requested device is not found OR it is not connected.
8160 --------------------------------------------------------------------------*/
8161v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8162{
8163 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8164 VOS_STATUS status;
8165 hdd_adapter_t *pAdapter;
8166 v_U8_t operatingChannel = 0;
8167
8168 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8169
8170 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8171 {
8172 pAdapter = pAdapterNode->pAdapter;
8173
8174 if( mode == pAdapter->device_mode )
8175 {
8176 switch(pAdapter->device_mode)
8177 {
8178 case WLAN_HDD_INFRA_STATION:
8179 case WLAN_HDD_P2P_CLIENT:
8180 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8181 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8182 break;
8183 case WLAN_HDD_SOFTAP:
8184 case WLAN_HDD_P2P_GO:
8185 /*softap connection info */
8186 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8187 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8188 break;
8189 default:
8190 break;
8191 }
8192
8193 break; //Found the device of interest. break the loop
8194 }
8195
8196 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8197 pAdapterNode = pNext;
8198 }
8199 return operatingChannel;
8200}
8201
8202#ifdef WLAN_FEATURE_PACKET_FILTERING
8203/**---------------------------------------------------------------------------
8204
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308205 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008206
8207 This used to set the multicast address list.
8208
8209 \param - dev - Pointer to the WLAN device.
8210 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308211 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008212
8213 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308214static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008215{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308216 hdd_adapter_t *pAdapter;
8217 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308219 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308221
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308222 ENTER();
8223
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308224 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308225 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008226 {
8227 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308228 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 return;
8230 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8232 ret = wlan_hdd_validate_context(pHddCtx);
8233 if (0 != ret)
8234 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308235 return;
8236 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 if (dev->flags & IFF_ALLMULTI)
8238 {
8239 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008240 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308241 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308243 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 {
8245 mc_count = netdev_mc_count(dev);
8246 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008247 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8249 {
8250 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008251 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308252 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 return;
8254 }
8255
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308256 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
8258 netdev_for_each_mc_addr(ha, dev) {
8259 if (i == mc_count)
8260 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308261 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8262 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308264 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308265 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 i++;
8267 }
8268 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308269
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05308270 if (pHddCtx->hdd_wlan_suspended)
8271 {
8272 /*
8273 * Configure the Mcast address list to FW
8274 * If wlan is already in suspend mode
8275 */
8276 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
8277 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308278 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 return;
8280}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308281
8282static void hdd_set_multicast_list(struct net_device *dev)
8283{
8284 vos_ssr_protect(__func__);
8285 __hdd_set_multicast_list(dev);
8286 vos_ssr_unprotect(__func__);
8287}
Jeff Johnson295189b2012-06-20 16:38:30 -07008288#endif
8289
8290/**---------------------------------------------------------------------------
8291
8292 \brief hdd_select_queue() -
8293
8294 This function is registered with the Linux OS for network
8295 core to decide which queue to use first.
8296
8297 \param - dev - Pointer to the WLAN device.
8298 - skb - Pointer to OS packet (sk_buff).
8299 \return - ac, Queue Index/access category corresponding to UP in IP header
8300
8301 --------------------------------------------------------------------------*/
8302v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308303 struct sk_buff *skb
8304#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8305 , void *accel_priv
8306#endif
8307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8308 , select_queue_fallback_t fallback
8309#endif
8310)
Jeff Johnson295189b2012-06-20 16:38:30 -07008311{
8312 return hdd_wmm_select_queue(dev, skb);
8313}
8314
8315
8316/**---------------------------------------------------------------------------
8317
8318 \brief hdd_wlan_initial_scan() -
8319
8320 This function triggers the initial scan
8321
8322 \param - pAdapter - Pointer to the HDD adapter.
8323
8324 --------------------------------------------------------------------------*/
8325void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8326{
8327 tCsrScanRequest scanReq;
8328 tCsrChannelInfo channelInfo;
8329 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008330 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008331 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8332
8333 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8334 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8335 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8336
8337 if(sme_Is11dSupported(pHddCtx->hHal))
8338 {
8339 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8340 if ( HAL_STATUS_SUCCESS( halStatus ) )
8341 {
8342 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8343 if( !scanReq.ChannelInfo.ChannelList )
8344 {
8345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8346 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008347 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 return;
8349 }
8350 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8351 channelInfo.numOfChannels);
8352 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8353 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008354 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 }
8356
8357 scanReq.scanType = eSIR_PASSIVE_SCAN;
8358 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8359 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8360 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8361 }
8362 else
8363 {
8364 scanReq.scanType = eSIR_ACTIVE_SCAN;
8365 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8366 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8367 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8368 }
8369
8370 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8371 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8372 {
8373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8374 __func__, halStatus );
8375 }
8376
8377 if(sme_Is11dSupported(pHddCtx->hHal))
8378 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8379}
8380
mukul sharmabab477d2015-06-11 17:14:55 +05308381void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8382{
8383 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8384 VOS_STATUS status;
8385 hdd_adapter_t *pAdapter;
8386
8387 ENTER();
8388
8389 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8390
8391 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8392 {
8393 pAdapter = pAdapterNode->pAdapter;
8394
8395 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8396 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8397 pAdapterNode = pNext;
8398 }
8399
8400 EXIT();
8401}
Jeff Johnson295189b2012-06-20 16:38:30 -07008402/**---------------------------------------------------------------------------
8403
8404 \brief hdd_full_power_callback() - HDD full power callback function
8405
8406 This is the function invoked by SME to inform the result of a full power
8407 request issued by HDD
8408
8409 \param - callbackcontext - Pointer to cookie
8410 \param - status - result of request
8411
8412 \return - None
8413
8414 --------------------------------------------------------------------------*/
8415static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8416{
Jeff Johnson72a40512013-12-19 10:14:15 -08008417 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008418
8419 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308420 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008421
8422 if (NULL == callbackContext)
8423 {
8424 hddLog(VOS_TRACE_LEVEL_ERROR,
8425 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008426 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 return;
8428 }
8429
Jeff Johnson72a40512013-12-19 10:14:15 -08008430 /* there is a race condition that exists between this callback
8431 function and the caller since the caller could time out either
8432 before or while this code is executing. we use a spinlock to
8433 serialize these actions */
8434 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
8436 if (POWER_CONTEXT_MAGIC != pContext->magic)
8437 {
8438 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008439 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 hddLog(VOS_TRACE_LEVEL_WARN,
8441 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008442 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 return;
8444 }
8445
Jeff Johnson72a40512013-12-19 10:14:15 -08008446 /* context is valid so caller is still waiting */
8447
8448 /* paranoia: invalidate the magic */
8449 pContext->magic = 0;
8450
8451 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008453
8454 /* serialization is complete */
8455 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008456}
8457
Katya Nigamf0511f62015-05-05 16:40:57 +05308458void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8459{
8460 pMonCtx->typeSubtypeBitmap = 0;
8461 if( type%10 ) /* Management Packets */
8462 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8463 type/=10;
8464 if( type%10 ) /* Control Packets */
8465 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8466 type/=10;
8467 if( type%10 ) /* Data Packets */
8468 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8469}
8470
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308471VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8472 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308473{
8474 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308475 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308476
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308477 if (MON_MODE_START == pMonCtx->state)
8478 monMsg.type = WDA_MON_START_REQ;
8479 else if (MON_MODE_STOP == pMonCtx->state)
8480 monMsg.type = WDA_MON_STOP_REQ;
8481 else {
8482 hddLog(VOS_TRACE_LEVEL_ERROR,
8483 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308484 return VOS_STATUS_E_FAILURE;
8485 }
8486
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308487 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8488 if (pMonModeReq == NULL) {
8489 hddLog(VOS_TRACE_LEVEL_ERROR,
8490 FL("fail to allocate memory for monitor mode req"));
8491 return VOS_STATUS_E_FAILURE;
8492 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308493
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308494 pMonModeReq->magic = magic;
8495 pMonModeReq->cmpVar = cmpVar;
8496 pMonModeReq->data = pMonCtx;
8497 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308498
Katya Nigamf0511f62015-05-05 16:40:57 +05308499 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308500 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308501 monMsg.bodyval = 0;
8502
8503 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8504 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8505 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308506 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308507 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308508 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308509}
8510
Katya Nigame7b69a82015-04-28 15:24:06 +05308511void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8512{
8513 VOS_STATUS vosStatus;
8514 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308515 long ret;
8516 hdd_mon_ctx_t *pMonCtx = NULL;
8517 v_U32_t magic;
8518 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308519
Katya Nigame7b69a82015-04-28 15:24:06 +05308520 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8521 if(pAdapter == NULL || pVosContext == NULL)
8522 {
8523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8524 return ;
8525 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308526
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308527 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8528 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8529 pMonCtx->state = MON_MODE_STOP;
8530 magic = MON_MODE_MSG_MAGIC;
8531 init_completion(&cmpVar);
8532 if (VOS_STATUS_SUCCESS !=
8533 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8534 pMonCtx, hdd_monPostMsgCb)) {
8535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8536 FL("failed to post MON MODE REQ"));
8537 pMonCtx->state = MON_MODE_START;
8538 magic = 0;
8539 return;
8540 }
8541 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8542 magic = 0;
8543 if (ret <= 0 ) {
8544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8545 FL("timeout on monitor mode completion %ld"), ret);
8546 }
8547 }
8548
Katya Nigame7b69a82015-04-28 15:24:06 +05308549 hdd_UnregisterWext(pAdapter->dev);
8550
8551 vos_mon_stop( pVosContext );
8552
8553 vosStatus = vos_sched_close( pVosContext );
8554 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8555 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8556 "%s: Failed to close VOSS Scheduler",__func__);
8557 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8558 }
8559
8560 vosStatus = vos_nv_close();
8561 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8562 {
8563 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8564 "%s: Failed to close NV", __func__);
8565 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8566 }
8567
8568 vos_close(pVosContext);
8569
8570 #ifdef WLAN_KD_READY_NOTIFIER
8571 nl_srv_exit(pHddCtx->ptt_pid);
8572 #else
8573 nl_srv_exit();
8574 #endif
8575
Katya Nigame7b69a82015-04-28 15:24:06 +05308576 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308577}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308578/**
8579 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
8580 * @ wiphy: the wiphy to validate against
8581 *
8582 * Return: void
8583 */
8584void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
8585{
8586 int i =0;
8587 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8588 {
8589 if (NULL != wiphy->bands[i] &&
8590 (NULL != wiphy->bands[i]->channels))
8591 {
8592 vos_mem_free(wiphy->bands[i]->channels);
8593 wiphy->bands[i]->channels = NULL;
8594 }
8595 }
8596}
Jeff Johnson295189b2012-06-20 16:38:30 -07008597/**---------------------------------------------------------------------------
8598
8599 \brief hdd_wlan_exit() - HDD WLAN exit function
8600
8601 This is the driver exit point (invoked during rmmod)
8602
8603 \param - pHddCtx - Pointer to the HDD Context
8604
8605 \return - None
8606
8607 --------------------------------------------------------------------------*/
8608void hdd_wlan_exit(hdd_context_t *pHddCtx)
8609{
8610 eHalStatus halStatus;
8611 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8612 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308613 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008614 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008615 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308617 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008618
8619 ENTER();
8620
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308621
Katya Nigame7b69a82015-04-28 15:24:06 +05308622 if (VOS_MONITOR_MODE == hdd_get_conparam())
8623 {
8624 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8625 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308626 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308627 }
8628 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008629 {
8630 // Unloading, restart logic is no more required.
8631 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008632
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308633#ifdef FEATURE_WLAN_TDLS
8634 /* At the time of driver unloading; if tdls connection is present;
8635 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8636 * wlan_hdd_tdls_find_peer always checks for valid context;
8637 * as load/unload in progress there can be a race condition.
8638 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8639 * when tdls state is enabled.
8640 * As soon as driver set load/unload flag; tdls flag also needs
8641 * to be disabled so that hdd_rx_packet_cbk won't call
8642 * wlan_hdd_tdls_find_peer.
8643 */
8644 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8645#endif
8646
c_hpothu5ab05e92014-06-13 17:34:05 +05308647 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8648 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308650 pAdapter = pAdapterNode->pAdapter;
8651 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308653 /* Disable TX on the interface, after this hard_start_xmit() will
8654 * not be called on that interface
8655 */
8656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8657 netif_tx_disable(pAdapter->dev);
8658
8659 /* Mark the interface status as "down" for outside world */
8660 netif_carrier_off(pAdapter->dev);
8661
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308662 /* DeInit the adapter. This ensures that all data packets
8663 * are freed.
8664 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308665#ifdef FEATURE_WLAN_TDLS
8666 mutex_lock(&pHddCtx->tdls_lock);
8667#endif
c_hpothu002231a2015-02-05 14:58:51 +05308668 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308669#ifdef FEATURE_WLAN_TDLS
8670 mutex_unlock(&pHddCtx->tdls_lock);
8671#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308672
c_hpothu5ab05e92014-06-13 17:34:05 +05308673 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8674 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8675 {
8676 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8677 hdd_UnregisterWext(pAdapter->dev);
8678 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308681 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8682 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 }
mukul sharmabab477d2015-06-11 17:14:55 +05308684
8685 //Purge all sme cmd's for all interface
8686 hdd_purge_cmd_list_all_adapters(pHddCtx);
8687
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308688 // Cancel any outstanding scan requests. We are about to close all
8689 // of our adapters, but an adapter structure is what SME passes back
8690 // to our callback function. Hence if there are any outstanding scan
8691 // requests then there is a race condition between when the adapter
8692 // is closed and when the callback is invoked.We try to resolve that
8693 // race condition here by canceling any outstanding scans before we
8694 // close the adapters.
8695 // Note that the scans may be cancelled in an asynchronous manner,
8696 // so ideally there needs to be some kind of synchronization. Rather
8697 // than introduce a new synchronization here, we will utilize the
8698 // fact that we are about to Request Full Power, and since that is
8699 // synchronized, the expectation is that by the time Request Full
8700 // Power has completed all scans will be cancelled.
8701 if (pHddCtx->scan_info.mScanPending)
8702 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308703 if(NULL != pAdapter)
8704 {
8705 hddLog(VOS_TRACE_LEVEL_INFO,
8706 FL("abort scan mode: %d sessionId: %d"),
8707 pAdapter->device_mode,
8708 pAdapter->sessionId);
8709 }
8710 hdd_abort_mac_scan(pHddCtx,
8711 pHddCtx->scan_info.sessionId,
8712 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308715 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008716 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308717 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308718 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8719 {
8720 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8722 "%s: in middle of FTM START", __func__);
8723 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8724 msecs_to_jiffies(20000));
8725 if(!lrc)
8726 {
8727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8728 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8729 }
8730 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008731 wlan_hdd_ftm_close(pHddCtx);
8732 goto free_hdd_ctx;
8733 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308734
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 /* DeRegister with platform driver as client for Suspend/Resume */
8736 vosStatus = hddDeregisterPmOps(pHddCtx);
8737 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8738 {
8739 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8740 VOS_ASSERT(0);
8741 }
8742
8743 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8744 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8745 {
8746 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8747 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008748
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008749 //Stop the traffic monitor timer
8750 if ( VOS_TIMER_STATE_RUNNING ==
8751 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8752 {
8753 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8754 }
8755
8756 // Destroy the traffic monitor timer
8757 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8758 &pHddCtx->tx_rx_trafficTmr)))
8759 {
8760 hddLog(VOS_TRACE_LEVEL_ERROR,
8761 "%s: Cannot deallocate Traffic monitor timer", __func__);
8762 }
8763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 //Disable IMPS/BMPS as we do not want the device to enter any power
8765 //save mode during shutdown
8766 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8767 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8768 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8769
8770 //Ensure that device is in full power as we will touch H/W during vos_Stop
8771 init_completion(&powerContext.completion);
8772 powerContext.magic = POWER_CONTEXT_MAGIC;
8773
8774 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8775 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8776
8777 if (eHAL_STATUS_SUCCESS != halStatus)
8778 {
8779 if (eHAL_STATUS_PMC_PENDING == halStatus)
8780 {
8781 /* request was sent -- wait for the response */
8782 lrc = wait_for_completion_interruptible_timeout(
8783 &powerContext.completion,
8784 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 if (lrc <= 0)
8786 {
8787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008788 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 }
8790 }
8791 else
8792 {
8793 hddLog(VOS_TRACE_LEVEL_ERROR,
8794 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008795 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 /* continue -- need to clean up as much as possible */
8797 }
8798 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308799 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8800 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8801 {
8802 /* This will issue a dump command which will clean up
8803 BTQM queues and unblock MC thread */
8804 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008806
Jeff Johnson72a40512013-12-19 10:14:15 -08008807 /* either we never sent a request, we sent a request and received a
8808 response or we sent a request and timed out. if we never sent a
8809 request or if we sent a request and got a response, we want to
8810 clear the magic out of paranoia. if we timed out there is a
8811 race condition such that the callback function could be
8812 executing at the same time we are. of primary concern is if the
8813 callback function had already verified the "magic" but had not
8814 yet set the completion variable when a timeout occurred. we
8815 serialize these activities by invalidating the magic while
8816 holding a shared spinlock which will cause us to block if the
8817 callback is currently executing */
8818 spin_lock(&hdd_context_lock);
8819 powerContext.magic = 0;
8820 spin_unlock(&hdd_context_lock);
8821
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308822 /* If Device is shutdown, no point for SME to wait for responses
8823 from device. Pre Close SME */
8824 if(wcnss_device_is_shutdown())
8825 {
8826 sme_PreClose(pHddCtx->hHal);
8827 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008828 hdd_debugfs_exit(pHddCtx);
8829
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308830#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308831 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308832 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8833#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308834 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308835 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8836
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 // Unregister the Net Device Notifier
8838 unregister_netdevice_notifier(&hdd_netdev_notifier);
8839
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 hdd_stop_all_adapters( pHddCtx );
8841
Jeff Johnson295189b2012-06-20 16:38:30 -07008842#ifdef WLAN_BTAMP_FEATURE
8843 vosStatus = WLANBAP_Stop(pVosContext);
8844 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8845 {
8846 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8847 "%s: Failed to stop BAP",__func__);
8848 }
8849#endif //WLAN_BTAMP_FEATURE
8850
8851 //Stop all the modules
8852 vosStatus = vos_stop( pVosContext );
8853 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8854 {
8855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8856 "%s: Failed to stop VOSS",__func__);
8857 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05308858 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 }
8860
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008863
8864 //Close the scheduler before calling vos_close to make sure no thread is
8865 // scheduled after the each module close is called i.e after all the data
8866 // structures are freed.
8867 vosStatus = vos_sched_close( pVosContext );
8868 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8869 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8870 "%s: Failed to close VOSS Scheduler",__func__);
8871 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8872 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008873#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8874 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308875 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008876#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008877 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308878 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008879
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308880#ifdef CONFIG_ENABLE_LINUX_REG
8881 vosStatus = vos_nv_close();
8882 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8883 {
8884 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8885 "%s: Failed to close NV", __func__);
8886 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8887 }
8888#endif
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 //Close VOSS
8891 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8892 vos_close(pVosContext);
8893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 //Close Watchdog
8895 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8896 vos_watchdog_close(pVosContext);
8897
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308898 //Clean up HDD Nlink Service
8899 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308900
c_manjeecfd1efb2015-09-25 19:32:34 +05308901 wlan_free_fwr_mem_dump_buffer();
8902 memdump_deinit();
8903
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308904#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308905 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308906 {
8907 wlan_logging_sock_deactivate_svc();
8908 }
8909#endif
8910
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308911#ifdef WLAN_KD_READY_NOTIFIER
8912 nl_srv_exit(pHddCtx->ptt_pid);
8913#else
8914 nl_srv_exit();
8915#endif /* WLAN_KD_READY_NOTIFIER */
8916
8917
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 hdd_close_all_adapters( pHddCtx );
8919
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05308920 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
8921
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308922free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 /* free the power on lock from platform driver */
8924 if (free_riva_power_on_lock("wlan"))
8925 {
8926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8927 __func__);
8928 }
8929
c_hpothu78c7b602014-05-17 17:35:49 +05308930 //Free up dynamically allocated members inside HDD Adapter
8931 if (pHddCtx->cfg_ini)
8932 {
8933 kfree(pHddCtx->cfg_ini);
8934 pHddCtx->cfg_ini= NULL;
8935 }
8936
Leo Changf04ddad2013-09-18 13:46:38 -07008937 /* FTM mode, WIPHY did not registered
8938 If un-register here, system crash will happen */
8939 if (VOS_FTM_MODE != hdd_get_conparam())
8940 {
8941 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308942 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -07008943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 if (hdd_is_ssr_required())
8946 {
8947 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008948 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 msleep(5000);
8950 }
8951 hdd_set_ssr_required (VOS_FALSE);
8952}
8953
8954
8955/**---------------------------------------------------------------------------
8956
8957 \brief hdd_update_config_from_nv() - Function to update the contents of
8958 the running configuration with parameters taken from NV storage
8959
8960 \param - pHddCtx - Pointer to the HDD global context
8961
8962 \return - VOS_STATUS_SUCCESS if successful
8963
8964 --------------------------------------------------------------------------*/
8965static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8966{
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 v_BOOL_t itemIsValid = VOS_FALSE;
8968 VOS_STATUS status;
8969 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8970 v_U8_t macLoop;
8971
8972 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8973 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8974 if(status != VOS_STATUS_SUCCESS)
8975 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008976 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 return VOS_STATUS_E_FAILURE;
8978 }
8979
8980 if (itemIsValid == VOS_TRUE)
8981 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008982 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8984 VOS_MAX_CONCURRENCY_PERSONA);
8985 if(status != VOS_STATUS_SUCCESS)
8986 {
8987 /* Get MAC from NV fail, not update CFG info
8988 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008989 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 return VOS_STATUS_E_FAILURE;
8991 }
8992
8993 /* If first MAC is not valid, treat all others are not valid
8994 * Then all MACs will be got from ini file */
8995 if(vos_is_macaddr_zero(&macFromNV[0]))
8996 {
8997 /* MAC address in NV file is not configured yet */
8998 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8999 return VOS_STATUS_E_INVAL;
9000 }
9001
9002 /* Get MAC address from NV, update CFG info */
9003 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
9004 {
9005 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
9006 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309007 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 /* This MAC is not valid, skip it
9009 * This MAC will be got from ini file */
9010 }
9011 else
9012 {
9013 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
9014 (v_U8_t *)&macFromNV[macLoop].bytes[0],
9015 VOS_MAC_ADDR_SIZE);
9016 }
9017 }
9018 }
9019 else
9020 {
9021 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
9022 return VOS_STATUS_E_FAILURE;
9023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009024
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
9026 return VOS_STATUS_SUCCESS;
9027}
9028
9029/**---------------------------------------------------------------------------
9030
9031 \brief hdd_post_voss_start_config() - HDD post voss start config helper
9032
9033 \param - pAdapter - Pointer to the HDD
9034
9035 \return - None
9036
9037 --------------------------------------------------------------------------*/
9038VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
9039{
9040 eHalStatus halStatus;
9041 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309042 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009043
Jeff Johnson295189b2012-06-20 16:38:30 -07009044
9045 // Send ready indication to the HDD. This will kick off the MAC
9046 // into a 'running' state and should kick off an initial scan.
9047 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9048 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9049 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309050 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 "code %08d [x%08x]",__func__, halStatus, halStatus );
9052 return VOS_STATUS_E_FAILURE;
9053 }
9054
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309055 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9057 // And RIVA will crash
9058 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9059 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309060 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9061 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9062
9063
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 return VOS_STATUS_SUCCESS;
9065}
9066
Jeff Johnson295189b2012-06-20 16:38:30 -07009067/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309068void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009069{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309070
9071 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9072
Jeff Johnson295189b2012-06-20 16:38:30 -07009073}
9074
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309075void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009076{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309077
9078 vos_wake_lock_release(&wlan_wake_lock, reason);
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080}
9081
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309082void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009083{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309084
9085 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9086 reason);
9087
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009088}
9089
Jeff Johnson295189b2012-06-20 16:38:30 -07009090/**---------------------------------------------------------------------------
9091
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009092 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9093 information between Host and Riva
9094
9095 This function gets reported version of FW
9096 It also finds the version of Riva headers used to compile the host
9097 It compares the above two and prints a warning if they are different
9098 It gets the SW and HW version string
9099 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9100 indicating the features they support through a bitmap
9101
9102 \param - pHddCtx - Pointer to HDD context
9103
9104 \return - void
9105
9106 --------------------------------------------------------------------------*/
9107
9108void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9109{
9110
9111 tSirVersionType versionCompiled;
9112 tSirVersionType versionReported;
9113 tSirVersionString versionString;
9114 tANI_U8 fwFeatCapsMsgSupported = 0;
9115 VOS_STATUS vstatus;
9116
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009117 memset(&versionCompiled, 0, sizeof(versionCompiled));
9118 memset(&versionReported, 0, sizeof(versionReported));
9119
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009120 /* retrieve and display WCNSS version information */
9121 do {
9122
9123 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9124 &versionCompiled);
9125 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9126 {
9127 hddLog(VOS_TRACE_LEVEL_FATAL,
9128 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009129 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009130 break;
9131 }
9132
9133 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9134 &versionReported);
9135 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9136 {
9137 hddLog(VOS_TRACE_LEVEL_FATAL,
9138 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009139 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009140 break;
9141 }
9142
9143 if ((versionCompiled.major != versionReported.major) ||
9144 (versionCompiled.minor != versionReported.minor) ||
9145 (versionCompiled.version != versionReported.version) ||
9146 (versionCompiled.revision != versionReported.revision))
9147 {
9148 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9149 "Host expected %u.%u.%u.%u\n",
9150 WLAN_MODULE_NAME,
9151 (int)versionReported.major,
9152 (int)versionReported.minor,
9153 (int)versionReported.version,
9154 (int)versionReported.revision,
9155 (int)versionCompiled.major,
9156 (int)versionCompiled.minor,
9157 (int)versionCompiled.version,
9158 (int)versionCompiled.revision);
9159 }
9160 else
9161 {
9162 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9163 WLAN_MODULE_NAME,
9164 (int)versionReported.major,
9165 (int)versionReported.minor,
9166 (int)versionReported.version,
9167 (int)versionReported.revision);
9168 }
9169
9170 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9171 versionString,
9172 sizeof(versionString));
9173 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9174 {
9175 hddLog(VOS_TRACE_LEVEL_FATAL,
9176 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009177 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009178 break;
9179 }
9180
9181 pr_info("%s: WCNSS software version %s\n",
9182 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +05309183 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009184
9185 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9186 versionString,
9187 sizeof(versionString));
9188 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9189 {
9190 hddLog(VOS_TRACE_LEVEL_FATAL,
9191 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009192 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009193 break;
9194 }
9195
9196 pr_info("%s: WCNSS hardware version %s\n",
9197 WLAN_MODULE_NAME, versionString);
9198
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009199 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9200 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009201 send the message only if it the riva is 1.1
9202 minor numbers for different riva branches:
9203 0 -> (1.0)Mainline Build
9204 1 -> (1.1)Mainline Build
9205 2->(1.04) Stability Build
9206 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009207 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009208 ((versionReported.minor>=1) && (versionReported.version>=1)))
9209 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9210 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009211
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009212 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009213 {
9214#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9215 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9216 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9217#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009218 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9219 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9220 {
9221 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9222 }
9223
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009224 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009225 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009226
9227 } while (0);
9228
9229}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309230void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9231{
9232 struct sk_buff *skb;
9233 struct nlmsghdr *nlh;
9234 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309235 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +05309236 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309237
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309238 if (in_interrupt() || irqs_disabled() || in_atomic())
9239 flags = GFP_ATOMIC;
9240
9241 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309242
9243 if(skb == NULL) {
9244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9245 "%s: alloc_skb failed", __func__);
9246 return;
9247 }
9248
9249 nlh = (struct nlmsghdr *)skb->data;
9250 nlh->nlmsg_pid = 0; /* from kernel */
9251 nlh->nlmsg_flags = 0;
9252 nlh->nlmsg_seq = 0;
9253 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9254
9255 ani_hdr = NLMSG_DATA(nlh);
9256 ani_hdr->type = type;
9257
9258 switch(type) {
9259 case WLAN_SVC_SAP_RESTART_IND:
9260 ani_hdr->length = 0;
9261 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9262 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9263 break;
Bhargav shah23c94942015-10-13 12:48:35 +05309264 case WLAN_MSG_RPS_ENABLE_IND:
9265 ani_hdr->length = len;
9266 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9267 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9268 memcpy(nl_data, data, len);
9269 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9270 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309271 default:
9272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9273 "Attempt to send unknown nlink message %d", type);
9274 kfree_skb(skb);
9275 return;
9276 }
9277
9278 nl_srv_bcast(skb);
9279
9280 return;
9281}
9282
9283
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009284
9285/**---------------------------------------------------------------------------
9286
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309287 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9288
9289 \param - pHddCtx - Pointer to the hdd context
9290
9291 \return - true if hardware supports 5GHz
9292
9293 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309294boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309295{
9296 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9297 * then hardware support 5Ghz.
9298 */
9299 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9300 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309302 return true;
9303 }
9304 else
9305 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309307 __func__);
9308 return false;
9309 }
9310}
9311
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309312/**---------------------------------------------------------------------------
9313
9314 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9315 generate function
9316
9317 This is generate the random mac address for WLAN interface
9318
9319 \param - pHddCtx - Pointer to HDD context
9320 idx - Start interface index to get auto
9321 generated mac addr.
9322 mac_addr - Mac address
9323
9324 \return - 0 for success, < 0 for failure
9325
9326 --------------------------------------------------------------------------*/
9327
9328static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9329 int idx, v_MACADDR_t mac_addr)
9330{
9331 int i;
9332 unsigned int serialno;
9333 serialno = wcnss_get_serial_number();
9334
9335 if (0 != serialno)
9336 {
9337 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9338 bytes of the serial number that can be used to generate
9339 the other 3 bytes of the MAC address. Mask off all but
9340 the lower 3 bytes (this will also make sure we don't
9341 overflow in the next step) */
9342 serialno &= 0x00FFFFFF;
9343
9344 /* we need a unique address for each session */
9345 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9346
9347 /* autogen other Mac addresses */
9348 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9349 {
9350 /* start with the entire default address */
9351 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9352 /* then replace the lower 3 bytes */
9353 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9354 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9355 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9356
9357 serialno++;
9358 hddLog(VOS_TRACE_LEVEL_ERROR,
9359 "%s: Derived Mac Addr: "
9360 MAC_ADDRESS_STR, __func__,
9361 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9362 }
9363
9364 }
9365 else
9366 {
9367 hddLog(LOGE, FL("Failed to Get Serial NO"));
9368 return -1;
9369 }
9370 return 0;
9371}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309372
Katya Nigame7b69a82015-04-28 15:24:06 +05309373int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9374{
9375 VOS_STATUS status;
9376 v_CONTEXT_t pVosContext= NULL;
9377 hdd_adapter_t *pAdapter= NULL;
9378
9379 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9380
9381 if (NULL == pVosContext)
9382 {
9383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9384 "%s: Trying to open VOSS without a PreOpen", __func__);
9385 VOS_ASSERT(0);
9386 return VOS_STATUS_E_FAILURE;
9387 }
9388
9389 status = vos_nv_open();
9390 if (!VOS_IS_STATUS_SUCCESS(status))
9391 {
9392 /* NV module cannot be initialized */
9393 hddLog( VOS_TRACE_LEVEL_FATAL,
9394 "%s: vos_nv_open failed", __func__);
9395 return VOS_STATUS_E_FAILURE;
9396 }
9397
9398 status = vos_init_wiphy_from_nv_bin();
9399 if (!VOS_IS_STATUS_SUCCESS(status))
9400 {
9401 /* NV module cannot be initialized */
9402 hddLog( VOS_TRACE_LEVEL_FATAL,
9403 "%s: vos_init_wiphy failed", __func__);
9404 goto err_vos_nv_close;
9405 }
9406
9407 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9408 if ( !VOS_IS_STATUS_SUCCESS( status ))
9409 {
9410 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9411 goto err_vos_nv_close;
9412 }
9413
9414 status = vos_mon_start( pVosContext );
9415 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9416 {
9417 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9418 goto err_vosclose;
9419 }
9420
9421 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9422 WDA_featureCapsExchange(pVosContext);
9423 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9424
9425 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9426 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9427 if( pAdapter == NULL )
9428 {
9429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9430 goto err_close_adapter;
9431 }
9432
9433 //Initialize the nlink service
9434 if(nl_srv_init() != 0)
9435 {
9436 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9437 goto err_close_adapter;
9438 }
9439 return VOS_STATUS_SUCCESS;
9440
9441err_close_adapter:
9442 hdd_close_all_adapters( pHddCtx );
9443 vos_mon_stop( pVosContext );
9444err_vosclose:
9445 status = vos_sched_close( pVosContext );
9446 if (!VOS_IS_STATUS_SUCCESS(status)) {
9447 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9448 "%s: Failed to close VOSS Scheduler", __func__);
9449 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9450 }
9451 vos_close(pVosContext );
9452
9453err_vos_nv_close:
9454 vos_nv_close();
9455
9456return status;
9457}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309458/**---------------------------------------------------------------------------
9459
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309460 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9461 completed to flush out the scan results
9462
9463 11d scan is done during driver load and is a passive scan on all
9464 channels supported by the device, 11d scans may find some APs on
9465 frequencies which are forbidden to be used in the regulatory domain
9466 the device is operating in. If these APs are notified to the supplicant
9467 it may try to connect to these APs, thus flush out all the scan results
9468 which are present in SME after 11d scan is done.
9469
9470 \return - eHalStatus
9471
9472 --------------------------------------------------------------------------*/
9473static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9474 tANI_U32 scanId, eCsrScanStatus status)
9475{
9476 ENTER();
9477
9478 sme_ScanFlushResult(halHandle, 0);
9479
9480 EXIT();
9481
9482 return eHAL_STATUS_SUCCESS;
9483}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309484/**---------------------------------------------------------------------------
9485
9486 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9487 logging is completed successfully.
9488
9489 \return - None
9490
9491 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +05309492void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309493{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309494 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309495
9496 if (NULL == pHddCtx)
9497 {
9498 hddLog(VOS_TRACE_LEVEL_ERROR,
9499 "%s: HDD context is NULL",__func__);
9500 return;
9501 }
9502
c_manjeecfd1efb2015-09-25 19:32:34 +05309503 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309504 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309505 {
9506 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9507 pHddCtx->mgmt_frame_logging = TRUE;
9508 }
9509 else
9510 {
9511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9512 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +05309513 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309514 }
9515
c_manjeecfd1efb2015-09-25 19:32:34 +05309516 /*Check feature supported by FW*/
9517 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
9518 {
9519 //Store fwr mem dump size given by firmware.
9520 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
9521 }
9522 else
9523 {
9524 wlan_store_fwr_mem_dump_size(0);
9525 }
9526
9527
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309528}
9529/**---------------------------------------------------------------------------
9530
9531 \brief hdd_init_frame_logging - function to initialize frame logging.
9532 Currently only Mgmt Frames are logged in both TX
9533 and Rx direction and are sent to userspace
9534 application using logger thread when queried.
9535
9536 \return - None
9537
9538 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309539void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309540{
9541 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309542 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309543
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309544 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9545 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309546 {
9547 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9548 return;
9549 }
9550
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309551 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9552 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309553 {
9554 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9555 return;
9556 }
9557
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309558 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309559
c_manjeecfd1efb2015-09-25 19:32:34 +05309560 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309561 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9562 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +05309563 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
9564 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309565
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309566 if (pHddCtx->cfg_ini->enableFWLogging ||
9567 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309568 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309569 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309570 }
9571
Sushant Kaushik46804902015-07-08 14:46:03 +05309572 if (pHddCtx->cfg_ini->enableMgmtLogging)
9573 {
9574 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9575 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309576 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9577 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309578 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309579 }
c_manjeecfd1efb2015-09-25 19:32:34 +05309580 if(pHddCtx->cfg_ini->enableFwrMemDump &&
9581 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
9582 {
9583 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
9584 }
9585 if( wlanFWLoggingInitParam->enableFlag == 0 )
9586 {
9587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
9588 return;
9589 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309590 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9591 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9592 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9593 wlanFWLoggingInitParam->continuousFrameLogging =
9594 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309595
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309596 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309597
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309598 wlanFWLoggingInitParam->minLogBufferSize =
9599 pHddCtx->cfg_ini->minLoggingBufferSize;
9600 wlanFWLoggingInitParam->maxLogBufferSize =
9601 pHddCtx->cfg_ini->maxLoggingBufferSize;
9602 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9603 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309604
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309605 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309606
9607 if (eHAL_STATUS_SUCCESS != halStatus)
9608 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309609 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309610 }
9611
9612 return;
9613}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309614
Bhargav shah23c94942015-10-13 12:48:35 +05309615static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
9616{
9617 hdd_adapter_t *adapter;
9618 hdd_adapter_list_node_t *adapter_node, *next;
9619 VOS_STATUS status = VOS_STATUS_SUCCESS;
9620 struct wlan_rps_data rps_data;
9621 int count;
9622
9623 if(!hdd_ctxt->cfg_ini->rps_mask)
9624 {
9625 return;
9626 }
9627
9628 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
9629 {
9630 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
9631 }
9632
9633 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
9634
9635 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
9636 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
9637 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
9638
9639 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
9640
9641 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
9642 {
9643 adapter = adapter_node->pAdapter;
9644 if (NULL != adapter) {
9645 strlcpy(rps_data.ifname, adapter->dev->name,
9646 sizeof(rps_data.ifname));
9647 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
9648 (void *)&rps_data,sizeof(rps_data));
9649 }
9650 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
9651 adapter_node = next;
9652 }
9653}
9654
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309655/**---------------------------------------------------------------------------
9656
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 \brief hdd_wlan_startup() - HDD init function
9658
9659 This is the driver startup code executed once a WLAN device has been detected
9660
9661 \param - dev - Pointer to the underlying device
9662
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009663 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009664
9665 --------------------------------------------------------------------------*/
9666
9667int hdd_wlan_startup(struct device *dev )
9668{
9669 VOS_STATUS status;
9670 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009671 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 hdd_context_t *pHddCtx = NULL;
9673 v_CONTEXT_t pVosContext= NULL;
9674#ifdef WLAN_BTAMP_FEATURE
9675 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9676 WLANBAP_ConfigType btAmpConfig;
9677 hdd_config_t *pConfig;
9678#endif
9679 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309681 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009682
9683 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 /*
9685 * cfg80211: wiphy allocation
9686 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309687 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009688
9689 if(wiphy == NULL)
9690 {
9691 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009692 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 pHddCtx = wiphy_priv(wiphy);
9695
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 //Initialize the adapter context to zeros.
9697 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9698
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309700 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309701 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009702
9703 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05309704 pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime();
Jeff Johnson295189b2012-06-20 16:38:30 -07009705
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309706 /* register for riva power on lock to platform driver
9707 * Locking power early to ensure FW doesn't reset by kernel while
9708 * host driver is busy initializing itself */
9709 if (req_riva_power_on_lock("wlan"))
9710 {
9711 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9712 __func__);
9713 goto err_free_hdd_context;
9714 }
9715
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 /*Get vos context here bcoz vos_open requires it*/
9717 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9718
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009719 if(pVosContext == NULL)
9720 {
9721 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9722 goto err_free_hdd_context;
9723 }
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 //Save the Global VOSS context in adapter context for future.
9726 pHddCtx->pvosContext = pVosContext;
9727
9728 //Save the adapter context in global context for future.
9729 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 pHddCtx->parent_dev = dev;
9732
9733 init_completion(&pHddCtx->full_pwr_comp_var);
9734 init_completion(&pHddCtx->standby_comp_var);
9735 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009736 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009737 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309738 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309739 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309740 init_completion(&pHddCtx->mc_sus_event_var);
9741 init_completion(&pHddCtx->tx_sus_event_var);
9742 init_completion(&pHddCtx->rx_sus_event_var);
9743
Amar Singhala49cbc52013-10-08 18:37:44 -07009744
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309745 hdd_init_ll_stats_ctx(pHddCtx);
9746
Amar Singhala49cbc52013-10-08 18:37:44 -07009747#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009748 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009749#else
9750 init_completion(&pHddCtx->driver_crda_req);
9751#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009752
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05309753#ifdef WLAN_FEATURE_EXTSCAN
9754 init_completion(&pHddCtx->ext_scan_context.response_event);
9755#endif /* WLAN_FEATURE_EXTSCAN */
9756
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309757 spin_lock_init(&pHddCtx->schedScan_lock);
9758
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9760
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05309761 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
9762 hdd_processSpoofMacAddrRequest);
9763
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309764#ifdef FEATURE_WLAN_TDLS
9765 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9766 * invoked by other instances also) to protect the concurrent
9767 * access for the Adapters by TDLS module.
9768 */
9769 mutex_init(&pHddCtx->tdls_lock);
9770#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309771 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309772 mutex_init(&pHddCtx->wmmLock);
9773
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05309774 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +05309775 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309776
Agarwal Ashish1f422872014-07-22 00:11:55 +05309777 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 // Load all config first as TL config is needed during vos_open
9779 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9780 if(pHddCtx->cfg_ini == NULL)
9781 {
9782 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9783 goto err_free_hdd_context;
9784 }
9785
9786 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9787
9788 // Read and parse the qcom_cfg.ini file
9789 status = hdd_parse_config_ini( pHddCtx );
9790 if ( VOS_STATUS_SUCCESS != status )
9791 {
9792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9793 __func__, WLAN_INI_FILE);
9794 goto err_config;
9795 }
Arif Hussaind5218912013-12-05 01:10:55 -08009796#ifdef MEMORY_DEBUG
9797 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9798 vos_mem_init();
9799
9800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9801 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9802#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009803
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309804 /* INI has been read, initialise the configuredMcastBcastFilter with
9805 * INI value as this will serve as the default value
9806 */
9807 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9808 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9809 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309810
9811 if (false == hdd_is_5g_supported(pHddCtx))
9812 {
9813 //5Ghz is not supported.
9814 if (1 != pHddCtx->cfg_ini->nBandCapability)
9815 {
9816 hddLog(VOS_TRACE_LEVEL_INFO,
9817 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9818 pHddCtx->cfg_ini->nBandCapability = 1;
9819 }
9820 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309821
9822 /* If SNR Monitoring is enabled, FW has to parse all beacons
9823 * for calcaluting and storing the average SNR, so set Nth beacon
9824 * filter to 1 to enable FW to parse all the beaocons
9825 */
9826 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9827 {
9828 /* The log level is deliberately set to WARN as overriding
9829 * nthBeaconFilter to 1 will increase power cosumption and this
9830 * might just prove helpful to detect the power issue.
9831 */
9832 hddLog(VOS_TRACE_LEVEL_WARN,
9833 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9834 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309837 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009839 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009841 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9842 {
9843 hddLog(VOS_TRACE_LEVEL_FATAL,
9844 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9845 goto err_config;
9846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009848
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009849 // Update VOS trace levels based upon the cfg.ini
9850 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9851 pHddCtx->cfg_ini->vosTraceEnableBAP);
9852 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9853 pHddCtx->cfg_ini->vosTraceEnableTL);
9854 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9855 pHddCtx->cfg_ini->vosTraceEnableWDI);
9856 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9857 pHddCtx->cfg_ini->vosTraceEnableHDD);
9858 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9859 pHddCtx->cfg_ini->vosTraceEnableSME);
9860 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9861 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309862 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9863 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009864 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9865 pHddCtx->cfg_ini->vosTraceEnableWDA);
9866 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9867 pHddCtx->cfg_ini->vosTraceEnableSYS);
9868 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9869 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009870 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9871 pHddCtx->cfg_ini->vosTraceEnableSAP);
9872 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9873 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009874
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 // Update WDI trace levels based upon the cfg.ini
9876 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9877 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9878 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9879 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9880 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9881 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9882 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9883 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009884
Jeff Johnson88ba7742013-02-27 14:36:02 -08009885 if (VOS_FTM_MODE == hdd_get_conparam())
9886 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9888 {
9889 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9890 goto err_free_hdd_context;
9891 }
9892 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309893 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309894 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009897
Katya Nigame7b69a82015-04-28 15:24:06 +05309898 if( VOS_MONITOR_MODE == hdd_get_conparam())
9899 {
9900 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9901 {
9902 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9903 goto err_free_hdd_context;
9904 }
9905 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9906 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9907 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9908 return VOS_STATUS_SUCCESS;
9909 }
9910
Jeff Johnson88ba7742013-02-27 14:36:02 -08009911 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9913 {
9914 status = vos_watchdog_open(pVosContext,
9915 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9916
9917 if(!VOS_IS_STATUS_SUCCESS( status ))
9918 {
9919 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309920 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 }
9922 }
9923
9924 pHddCtx->isLogpInProgress = FALSE;
9925 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9926
Amar Singhala49cbc52013-10-08 18:37:44 -07009927#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009928 /* initialize the NV module. This is required so that
9929 we can initialize the channel information in wiphy
9930 from the NV.bin data. The channel information in
9931 wiphy needs to be initialized before wiphy registration */
9932
9933 status = vos_nv_open();
9934 if (!VOS_IS_STATUS_SUCCESS(status))
9935 {
9936 /* NV module cannot be initialized */
9937 hddLog( VOS_TRACE_LEVEL_FATAL,
9938 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309939 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009940 }
9941
9942 status = vos_init_wiphy_from_nv_bin();
9943 if (!VOS_IS_STATUS_SUCCESS(status))
9944 {
9945 /* NV module cannot be initialized */
9946 hddLog( VOS_TRACE_LEVEL_FATAL,
9947 "%s: vos_init_wiphy failed", __func__);
9948 goto err_vos_nv_close;
9949 }
9950
Amar Singhala49cbc52013-10-08 18:37:44 -07009951#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309952 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309953 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 if ( !VOS_IS_STATUS_SUCCESS( status ))
9955 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009956 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309957 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 }
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9961
9962 if ( NULL == pHddCtx->hHal )
9963 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009964 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 goto err_vosclose;
9966 }
9967
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009968 status = vos_preStart( pHddCtx->pvosContext );
9969 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9970 {
9971 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309972 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009973 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009974
Arif Hussaineaf68602013-12-30 23:10:44 -08009975 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9976 {
9977 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9979 __func__, enable_dfs_chan_scan);
9980 }
9981 if (0 == enable_11d || 1 == enable_11d)
9982 {
9983 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9984 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9985 __func__, enable_11d);
9986 }
9987
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009988 /* Note that the vos_preStart() sequence triggers the cfg download.
9989 The cfg download must occur before we update the SME config
9990 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 status = hdd_set_sme_config( pHddCtx );
9992
9993 if ( VOS_STATUS_SUCCESS != status )
9994 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009995 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309996 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009998
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 /* In the integrated architecture we update the configuration from
10000 the INI file and from NV before vOSS has been started so that
10001 the final contents are available to send down to the cCPU */
10002
10003 // Apply the cfg.ini to cfg.dat
10004 if (FALSE == hdd_update_config_dat(pHddCtx))
10005 {
10006 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010007 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 }
10009
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010010 // Get mac addr from platform driver
10011 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
10012
10013 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010015 /* Store the mac addr for first interface */
10016 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
10017
10018 hddLog(VOS_TRACE_LEVEL_ERROR,
10019 "%s: WLAN Mac Addr: "
10020 MAC_ADDRESS_STR, __func__,
10021 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10022
10023 /* Here, passing Arg2 as 1 because we do not want to change the
10024 last 3 bytes (means non OUI bytes) of first interface mac
10025 addr.
10026 */
10027 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
10028 {
10029 hddLog(VOS_TRACE_LEVEL_ERROR,
10030 "%s: Failed to generate wlan interface mac addr "
10031 "using MAC from ini file ", __func__);
10032 }
10033 }
10034 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
10035 {
10036 // Apply the NV to cfg.dat
10037 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070010038#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
10039 /* There was not a valid set of MAC Addresses in NV. See if the
10040 default addresses were modified by the cfg.ini settings. If so,
10041 we'll use them, but if not, we'll autogenerate a set of MAC
10042 addresses based upon the device serial number */
10043
10044 static const v_MACADDR_t default_address =
10045 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070010046
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010047 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
10048 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 {
10050 /* cfg.ini has the default address, invoke autogen logic */
10051
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010052 /* Here, passing Arg2 as 0 because we want to change the
10053 last 3 bytes (means non OUI bytes) of all the interfaces
10054 mac addr.
10055 */
10056 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
10057 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010059 hddLog(VOS_TRACE_LEVEL_ERROR,
10060 "%s: Failed to generate wlan interface mac addr "
10061 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
10062 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 }
10065 else
10066#endif //WLAN_AUTOGEN_MACADDR_FEATURE
10067 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010068 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 "%s: Invalid MAC address in NV, using MAC from ini file "
10070 MAC_ADDRESS_STR, __func__,
10071 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10072 }
10073 }
10074 {
10075 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010076
10077 /* Set the MAC Address Currently this is used by HAL to
10078 * add self sta. Remove this once self sta is added as
10079 * part of session open.
10080 */
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
10082 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
10083 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010084
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 if (!HAL_STATUS_SUCCESS( halStatus ))
10086 {
10087 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
10088 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010089 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 }
10091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010092
10093 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
10094 Note: Firmware image will be read and downloaded inside vos_start API */
10095 status = vos_start( pHddCtx->pvosContext );
10096 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10097 {
10098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +053010099 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010100 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 }
10102
Leo Chang6cec3e22014-01-21 15:33:49 -080010103#ifdef FEATURE_WLAN_CH_AVOID
10104 /* Plug in avoid channel notification callback
10105 * This should happen before ADD_SELF_STA
10106 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010107
10108 /* check the Channel Avoidance is enabled */
10109 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10110 {
10111 sme_AddChAvoidCallback(pHddCtx->hHal,
10112 hdd_hostapd_ch_avoid_cb);
10113 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010114#endif /* FEATURE_WLAN_CH_AVOID */
10115
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010116 /* Exchange capability info between Host and FW and also get versioning info from FW */
10117 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010119#ifdef CONFIG_ENABLE_LINUX_REG
10120 status = wlan_hdd_init_channels(pHddCtx);
10121 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10122 {
10123 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10124 __func__);
10125 goto err_vosstop;
10126 }
10127#endif
10128
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 status = hdd_post_voss_start_config( pHddCtx );
10130 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10131 {
10132 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10133 __func__);
10134 goto err_vosstop;
10135 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010136
10137#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010138 wlan_hdd_cfg80211_update_reg_info( wiphy );
10139
10140 /* registration of wiphy dev with cfg80211 */
10141 if (0 > wlan_hdd_cfg80211_register(wiphy))
10142 {
10143 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10144 goto err_vosstop;
10145 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010146#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010147
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010148#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010149 /* registration of wiphy dev with cfg80211 */
10150 if (0 > wlan_hdd_cfg80211_register(wiphy))
10151 {
10152 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10153 goto err_vosstop;
10154 }
10155
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010156 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010157 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10158 {
10159 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10160 __func__);
10161 goto err_unregister_wiphy;
10162 }
10163#endif
10164
c_hpothu4a298be2014-12-22 21:12:51 +053010165 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10166
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10168 {
10169 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10170 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10171 }
10172 else
10173 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010174 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10175 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10176 if (pAdapter != NULL)
10177 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010178 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010180 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10181 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10182 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010183
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010184 /* Generate the P2P Device Address. This consists of the device's
10185 * primary MAC address with the locally administered bit set.
10186 */
10187 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010188 }
10189 else
10190 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010191 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10192 if (p2p_dev_addr != NULL)
10193 {
10194 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10195 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10196 }
10197 else
10198 {
10199 hddLog(VOS_TRACE_LEVEL_FATAL,
10200 "%s: Failed to allocate mac_address for p2p_device",
10201 __func__);
10202 goto err_close_adapter;
10203 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010205
10206 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10207 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10208 if ( NULL == pP2pAdapter )
10209 {
10210 hddLog(VOS_TRACE_LEVEL_FATAL,
10211 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010212 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010213 goto err_close_adapter;
10214 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010217
10218 if( pAdapter == NULL )
10219 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10221 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010222 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010223
Arif Hussain66559122013-11-21 10:11:40 -080010224 if (country_code)
10225 {
10226 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010227 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010228 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10229#ifndef CONFIG_ENABLE_LINUX_REG
10230 hdd_checkandupdate_phymode(pAdapter, country_code);
10231#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010232 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10233 (void *)(tSmeChangeCountryCallback)
10234 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010235 country_code,
10236 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010237 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010238 if (eHAL_STATUS_SUCCESS == ret)
10239 {
Arif Hussaincb607082013-12-20 11:57:42 -080010240 ret = wait_for_completion_interruptible_timeout(
10241 &pAdapter->change_country_code,
10242 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10243
10244 if (0 >= ret)
10245 {
10246 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10247 "%s: SME while setting country code timed out", __func__);
10248 }
Arif Hussain66559122013-11-21 10:11:40 -080010249 }
10250 else
10251 {
Arif Hussaincb607082013-12-20 11:57:42 -080010252 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10253 "%s: SME Change Country code from module param fail ret=%d",
10254 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010255 }
10256 }
10257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258#ifdef WLAN_BTAMP_FEATURE
10259 vStatus = WLANBAP_Open(pVosContext);
10260 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10261 {
10262 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10263 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010264 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 }
10266
10267 vStatus = BSL_Init(pVosContext);
10268 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10269 {
10270 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10271 "%s: Failed to Init BSL",__func__);
10272 goto err_bap_close;
10273 }
10274 vStatus = WLANBAP_Start(pVosContext);
10275 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10276 {
10277 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10278 "%s: Failed to start TL",__func__);
10279 goto err_bap_close;
10280 }
10281
10282 pConfig = pHddCtx->cfg_ini;
10283 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10284 status = WLANBAP_SetConfig(&btAmpConfig);
10285
10286#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010287
Mihir Shete9c238772014-10-15 14:35:16 +053010288 /*
10289 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10290 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10291 * which is greater than 0xf. So the below check is safe to make
10292 * sure that there is no entry for UapsdMask in the ini
10293 */
10294 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10295 {
10296 if(IS_DYNAMIC_WMM_PS_ENABLED)
10297 {
10298 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10299 __func__);
10300 pHddCtx->cfg_ini->UapsdMask =
10301 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10302 }
10303 else
10304 {
10305 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10306 __func__);
10307 pHddCtx->cfg_ini->UapsdMask =
10308 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10309 }
10310 }
10311
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010312#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10313 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10314 {
10315 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10316 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10317 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10318 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10319 }
10320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010321
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010322 wlan_hdd_tdls_init(pHddCtx);
10323
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010324 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 /* Register with platform driver as client for Suspend/Resume */
10327 status = hddRegisterPmOps(pHddCtx);
10328 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10329 {
10330 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10331#ifdef WLAN_BTAMP_FEATURE
10332 goto err_bap_stop;
10333#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010334 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010335#endif //WLAN_BTAMP_FEATURE
10336 }
10337
Yue Ma0d4891e2013-08-06 17:01:45 -070010338 /* Open debugfs interface */
10339 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10340 {
10341 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10342 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010343 }
10344
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 /* Register TM level change handler function to the platform */
10346 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10347 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10348 {
10349 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10350 goto err_unregister_pmops;
10351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010352
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 // register net device notifier for device change notification
10354 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10355
10356 if(ret < 0)
10357 {
10358 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010359 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 }
10361
10362 //Initialize the nlink service
10363 if(nl_srv_init() != 0)
10364 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010365 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 goto err_reg_netdev;
10367 }
10368
Leo Chang4ce1cc52013-10-21 18:27:15 -070010369#ifdef WLAN_KD_READY_NOTIFIER
10370 pHddCtx->kd_nl_init = 1;
10371#endif /* WLAN_KD_READY_NOTIFIER */
10372
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 //Initialize the BTC service
10374 if(btc_activate_service(pHddCtx) != 0)
10375 {
10376 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10377 goto err_nl_srv;
10378 }
10379
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053010380#ifdef FEATURE_OEM_DATA_SUPPORT
10381 //Initialize the OEM service
10382 if (oem_activate_service(pHddCtx) != 0)
10383 {
10384 hddLog(VOS_TRACE_LEVEL_FATAL,
10385 "%s: oem_activate_service failed", __func__);
10386 goto err_nl_srv;
10387 }
10388#endif
10389
Jeff Johnson295189b2012-06-20 16:38:30 -070010390#ifdef PTT_SOCK_SVC_ENABLE
10391 //Initialize the PTT service
10392 if(ptt_sock_activate_svc(pHddCtx) != 0)
10393 {
10394 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10395 goto err_nl_srv;
10396 }
10397#endif
10398
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010399#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10400 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10401 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010402 if(wlan_logging_sock_activate_svc(
10403 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053010404 pHddCtx->cfg_ini->wlanLoggingNumBuf,
10405 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
10406 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053010407 {
10408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10409 " failed", __func__);
10410 goto err_nl_srv;
10411 }
10412 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10413 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010414 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10415 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053010416 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
10417 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010418 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010419
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010420 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10421 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010422 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053010423 pHddCtx->cfg_ini->enableContFWLogging ||
10424 pHddCtx->cfg_ini->enableFwrMemDump )
10425 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010426 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010427 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010428 }
10429 else
10430 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010431 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010432 }
10433
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010434#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010435
10436
Sushant Kaushik215778f2015-05-21 14:05:36 +053010437 if (vos_is_multicast_logging())
10438 wlan_logging_set_log_level();
10439
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010443 /* Action frame registered in one adapter which will
10444 * applicable to all interfaces
10445 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010446 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010448
10449 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010450 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010451
Jeff Johnsone7245742012-09-05 17:12:55 -070010452#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10453 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010454 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010455 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010456
Jeff Johnsone7245742012-09-05 17:12:55 -070010457#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010458 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010459 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010460 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010461
Jeff Johnsone7245742012-09-05 17:12:55 -070010462
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010463 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10464 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010465
Katya Nigam5c306ea2014-06-19 15:39:54 +053010466 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010468 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010469
10470#ifdef FEATURE_WLAN_SCAN_PNO
10471 /*SME must send channel update configuration to RIVA*/
10472 sme_UpdateChannelConfig(pHddCtx->hHal);
10473#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010474 /* Send the update default channel list to the FW*/
10475 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010476
10477 /* Fwr capabilities received, Set the Dot11 mode */
10478 sme_SetDefDot11Mode(pHddCtx->hHal);
10479
Abhishek Singha306a442013-11-07 18:39:01 +053010480#ifndef CONFIG_ENABLE_LINUX_REG
10481 /*updating wiphy so that regulatory user hints can be processed*/
10482 if (wiphy)
10483 {
10484 regulatory_hint(wiphy, "00");
10485 }
10486#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010487 // Initialize the restart logic
10488 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010489
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010490 //Register the traffic monitor timer now
10491 if ( pHddCtx->cfg_ini->dynSplitscan)
10492 {
10493 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10494 VOS_TIMER_TYPE_SW,
10495 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10496 (void *)pHddCtx);
10497 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010498 wlan_hdd_cfg80211_nan_init(pHddCtx);
10499
Dino Mycle6fb96c12014-06-10 11:52:40 +053010500#ifdef WLAN_FEATURE_EXTSCAN
10501 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10502 wlan_hdd_cfg80211_extscan_callback,
10503 pHddCtx);
10504#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010505
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053010506#ifdef FEATURE_OEM_DATA_SUPPORT
10507 sme_OemDataRegisterCallback(pHddCtx->hHal,
10508 wlan_hdd_cfg80211_oemdata_callback,
10509 pHddCtx);
10510#endif /* FEATURE_OEM_DATA_SUPPORT */
10511
Gupta, Kapil7c34b322015-09-30 13:12:35 +053010512 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010513#ifdef WLAN_NS_OFFLOAD
10514 // Register IPv6 notifier to notify if any change in IP
10515 // So that we can reconfigure the offload parameters
10516 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10517 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10518 if (ret)
10519 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010521 }
10522 else
10523 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010525 }
10526#endif
10527
10528 // Register IPv4 notifier to notify if any change in IP
10529 // So that we can reconfigure the offload parameters
10530 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10531 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10532 if (ret)
10533 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010535 }
10536 else
10537 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010538 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010539 }
c_manjeecfd1efb2015-09-25 19:32:34 +053010540 /*Fw mem dump procfs initialization*/
10541 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053010542 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010543
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 goto success;
10545
10546err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010547#ifdef WLAN_KD_READY_NOTIFIER
10548 nl_srv_exit(pHddCtx->ptt_pid);
10549#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010551#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010552err_reg_netdev:
10553 unregister_netdevice_notifier(&hdd_netdev_notifier);
10554
Jeff Johnson295189b2012-06-20 16:38:30 -070010555err_unregister_pmops:
10556 hddDevTmUnregisterNotifyCallback(pHddCtx);
10557 hddDeregisterPmOps(pHddCtx);
10558
Yue Ma0d4891e2013-08-06 17:01:45 -070010559 hdd_debugfs_exit(pHddCtx);
10560
Jeff Johnson295189b2012-06-20 16:38:30 -070010561#ifdef WLAN_BTAMP_FEATURE
10562err_bap_stop:
10563 WLANBAP_Stop(pVosContext);
10564#endif
10565
10566#ifdef WLAN_BTAMP_FEATURE
10567err_bap_close:
10568 WLANBAP_Close(pVosContext);
10569#endif
10570
Jeff Johnson295189b2012-06-20 16:38:30 -070010571err_close_adapter:
10572 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010573#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010574err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010575#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010576 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010577 hdd_wlan_free_wiphy_channels(wiphy);
10578
Jeff Johnson295189b2012-06-20 16:38:30 -070010579err_vosstop:
10580 vos_stop(pVosContext);
10581
Amar Singhala49cbc52013-10-08 18:37:44 -070010582err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 status = vos_sched_close( pVosContext );
10584 if (!VOS_IS_STATUS_SUCCESS(status)) {
10585 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10586 "%s: Failed to close VOSS Scheduler", __func__);
10587 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10588 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010589 vos_close(pVosContext );
10590
Amar Singhal0a402232013-10-11 20:57:16 -070010591err_vos_nv_close:
10592
c_hpothue6a36282014-03-19 12:27:38 +053010593#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010594 vos_nv_close();
10595
c_hpothu70f8d812014-03-22 22:59:23 +053010596#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010597
10598err_wdclose:
10599 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10600 vos_watchdog_close(pVosContext);
10601
Jeff Johnson295189b2012-06-20 16:38:30 -070010602err_config:
10603 kfree(pHddCtx->cfg_ini);
10604 pHddCtx->cfg_ini= NULL;
10605
10606err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010607 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010608 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 wiphy_free(wiphy) ;
10610 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 VOS_BUG(1);
10612
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010613 if (hdd_is_ssr_required())
10614 {
10615 /* WDI timeout had happened during load, so SSR is needed here */
10616 subsystem_restart("wcnss");
10617 msleep(5000);
10618 }
10619 hdd_set_ssr_required (VOS_FALSE);
10620
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010621 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010622
10623success:
10624 EXIT();
10625 return 0;
10626}
10627
10628/**---------------------------------------------------------------------------
10629
Jeff Johnson32d95a32012-09-10 13:15:23 -070010630 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010631
Jeff Johnson32d95a32012-09-10 13:15:23 -070010632 This is the driver entry point - called in different timeline depending
10633 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010634
10635 \param - None
10636
10637 \return - 0 for success, non zero for failure
10638
10639 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010640static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010641{
10642 VOS_STATUS status;
10643 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 struct device *dev = NULL;
10645 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010646#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10647 int max_retries = 0;
10648#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010649#ifdef HAVE_CBC_DONE
10650 int max_cbc_retries = 0;
10651#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010652
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010653#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10654 wlan_logging_sock_init_svc();
10655#endif
10656
Jeff Johnson295189b2012-06-20 16:38:30 -070010657 ENTER();
10658
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010659 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010660
10661 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10662 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10663
Jeff Johnson295189b2012-06-20 16:38:30 -070010664#ifdef ANI_BUS_TYPE_PCI
10665
10666 dev = wcnss_wlan_get_device();
10667
10668#endif // ANI_BUS_TYPE_PCI
10669
10670#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010671
10672#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10673 /* wait until WCNSS driver downloads NV */
10674 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10675 msleep(1000);
10676 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010677
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010678 if (max_retries >= 5) {
10679 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010680 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010681#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10682 wlan_logging_sock_deinit_svc();
10683#endif
10684
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010685 return -ENODEV;
10686 }
10687#endif
10688
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010689#ifdef HAVE_CBC_DONE
10690 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10691 msleep(1000);
10692 }
10693 if (max_cbc_retries >= 10) {
10694 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10695 }
10696#endif
10697
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 dev = wcnss_wlan_get_device();
10699#endif // ANI_BUS_TYPE_PLATFORM
10700
10701
10702 do {
10703 if (NULL == dev) {
10704 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10705 ret_status = -1;
10706 break;
10707 }
10708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709#ifdef TIMER_MANAGER
10710 vos_timer_manager_init();
10711#endif
10712
10713 /* Preopen VOSS so that it is ready to start at least SAL */
10714 status = vos_preOpen(&pVosContext);
10715
10716 if (!VOS_IS_STATUS_SUCCESS(status))
10717 {
10718 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10719 ret_status = -1;
10720 break;
10721 }
10722
Sushant Kaushik02beb352015-06-04 15:15:01 +053010723 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053010724 hdd_register_debug_callback();
10725
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010726#ifndef MODULE
10727 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10728 */
10729 hdd_set_conparam((v_UINT_t)con_mode);
10730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010731
10732 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010733 if (hdd_wlan_startup(dev))
10734 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010735 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010736 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 vos_preClose( &pVosContext );
10738 ret_status = -1;
10739 break;
10740 }
10741
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 } while (0);
10743
10744 if (0 != ret_status)
10745 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010746#ifdef TIMER_MANAGER
10747 vos_timer_exit();
10748#endif
10749#ifdef MEMORY_DEBUG
10750 vos_mem_exit();
10751#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010752 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010753#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10754 wlan_logging_sock_deinit_svc();
10755#endif
10756
Jeff Johnson295189b2012-06-20 16:38:30 -070010757 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10758 }
10759 else
10760 {
10761 //Send WLAN UP indication to Nlink Service
10762 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10763
10764 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 }
10766
10767 EXIT();
10768
10769 return ret_status;
10770}
10771
Jeff Johnson32d95a32012-09-10 13:15:23 -070010772/**---------------------------------------------------------------------------
10773
10774 \brief hdd_module_init() - Init Function
10775
10776 This is the driver entry point (invoked when module is loaded using insmod)
10777
10778 \param - None
10779
10780 \return - 0 for success, non zero for failure
10781
10782 --------------------------------------------------------------------------*/
10783#ifdef MODULE
10784static int __init hdd_module_init ( void)
10785{
10786 return hdd_driver_init();
10787}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010788#else /* #ifdef MODULE */
10789static int __init hdd_module_init ( void)
10790{
10791 /* Driver initialization is delayed to fwpath_changed_handler */
10792 return 0;
10793}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010794#endif /* #ifdef MODULE */
10795
Jeff Johnson295189b2012-06-20 16:38:30 -070010796
10797/**---------------------------------------------------------------------------
10798
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010799 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010800
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010801 This is the driver exit point (invoked when module is unloaded using rmmod
10802 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010803
10804 \param - None
10805
10806 \return - None
10807
10808 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010809static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010810{
10811 hdd_context_t *pHddCtx = NULL;
10812 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010813 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010814 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010815
10816 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10817
10818 //Get the global vos context
10819 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10820
10821 if(!pVosContext)
10822 {
10823 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10824 goto done;
10825 }
10826
10827 //Get the HDD context.
10828 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10829
10830 if(!pHddCtx)
10831 {
10832 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10833 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010834 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10835 {
10836 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10837 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10838 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10839 hdd_wlan_exit(pHddCtx);
10840 vos_preClose( &pVosContext );
10841 goto done;
10842 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 else
10844 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010845 /* We wait for active entry threads to exit from driver
10846 * by waiting until rtnl_lock is available.
10847 */
10848 rtnl_lock();
10849 rtnl_unlock();
10850
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010851 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10852 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10853 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10854 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010856 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010857 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10858 msecs_to_jiffies(30000));
10859 if(!rc)
10860 {
10861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10862 "%s:SSR timedout, fatal error", __func__);
10863 VOS_BUG(0);
10864 }
10865 }
10866
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010867 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10868 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010869
c_hpothu8adb97b2014-12-08 19:38:20 +053010870 /* Driver Need to send country code 00 in below condition
10871 * 1) If gCountryCodePriority is set to 1; and last country
10872 * code set is through 11d. This needs to be done in case
10873 * when NV country code is 00.
10874 * This Needs to be done as when kernel store last country
10875 * code and if stored country code is not through 11d,
10876 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10877 * in next load/unload as soon as we get any country through
10878 * 11d. In sme_HandleChangeCountryCodeByUser
10879 * pMsg->countryCode will be last countryCode and
10880 * pMac->scan.countryCode11d will be country through 11d so
10881 * due to mismatch driver will disable 11d.
10882 *
10883 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010884
c_hpothu8adb97b2014-12-08 19:38:20 +053010885 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010886 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010887 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010888 {
10889 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010890 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010891 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10892 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010893
c_hpothu8adb97b2014-12-08 19:38:20 +053010894 //Do all the cleanup before deregistering the driver
10895 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 }
10897
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 vos_preClose( &pVosContext );
10899
10900#ifdef TIMER_MANAGER
10901 vos_timer_exit();
10902#endif
10903#ifdef MEMORY_DEBUG
10904 vos_mem_exit();
10905#endif
10906
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010907#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10908 wlan_logging_sock_deinit_svc();
10909#endif
10910
Jeff Johnson295189b2012-06-20 16:38:30 -070010911done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010912 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010913
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10915}
10916
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010917/**---------------------------------------------------------------------------
10918
10919 \brief hdd_module_exit() - Exit function
10920
10921 This is the driver exit point (invoked when module is unloaded using rmmod)
10922
10923 \param - None
10924
10925 \return - None
10926
10927 --------------------------------------------------------------------------*/
10928static void __exit hdd_module_exit(void)
10929{
10930 hdd_driver_exit();
10931}
10932
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010933#ifdef MODULE
10934static int fwpath_changed_handler(const char *kmessage,
10935 struct kernel_param *kp)
10936{
Jeff Johnson76052702013-04-16 13:55:05 -070010937 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010938}
10939
10940static int con_mode_handler(const char *kmessage,
10941 struct kernel_param *kp)
10942{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010943 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010944}
10945#else /* #ifdef MODULE */
10946/**---------------------------------------------------------------------------
10947
Jeff Johnson76052702013-04-16 13:55:05 -070010948 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010949
Jeff Johnson76052702013-04-16 13:55:05 -070010950 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010951 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010952 - invoked when module parameter fwpath is modified from userspace to signal
10953 initializing the WLAN driver or when con_mode is modified from userspace
10954 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010955
10956 \return - 0 for success, non zero for failure
10957
10958 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010959static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010960{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010961 int ret_status;
10962
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010963 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010964 ret_status = hdd_driver_init();
10965 wlan_hdd_inited = ret_status ? 0 : 1;
10966 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010967 }
10968
10969 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010970
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010971 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010972
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010973 ret_status = hdd_driver_init();
10974 wlan_hdd_inited = ret_status ? 0 : 1;
10975 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010976}
10977
Jeff Johnson295189b2012-06-20 16:38:30 -070010978/**---------------------------------------------------------------------------
10979
Jeff Johnson76052702013-04-16 13:55:05 -070010980 \brief fwpath_changed_handler() - Handler Function
10981
10982 Handle changes to the fwpath parameter
10983
10984 \return - 0 for success, non zero for failure
10985
10986 --------------------------------------------------------------------------*/
10987static int fwpath_changed_handler(const char *kmessage,
10988 struct kernel_param *kp)
10989{
10990 int ret;
10991
10992 ret = param_set_copystring(kmessage, kp);
10993 if (0 == ret)
10994 ret = kickstart_driver();
10995 return ret;
10996}
10997
10998/**---------------------------------------------------------------------------
10999
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011000 \brief con_mode_handler() -
11001
11002 Handler function for module param con_mode when it is changed by userspace
11003 Dynamically linked - do nothing
11004 Statically linked - exit and init driver, as in rmmod and insmod
11005
Jeff Johnson76052702013-04-16 13:55:05 -070011006 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011007
Jeff Johnson76052702013-04-16 13:55:05 -070011008 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011009
11010 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070011011static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011012{
Jeff Johnson76052702013-04-16 13:55:05 -070011013 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011014
Jeff Johnson76052702013-04-16 13:55:05 -070011015 ret = param_set_int(kmessage, kp);
11016 if (0 == ret)
11017 ret = kickstart_driver();
11018 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011019}
11020#endif /* #ifdef MODULE */
11021
11022/**---------------------------------------------------------------------------
11023
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 \brief hdd_get_conparam() -
11025
11026 This is the driver exit point (invoked when module is unloaded using rmmod)
11027
11028 \param - None
11029
11030 \return - tVOS_CON_MODE
11031
11032 --------------------------------------------------------------------------*/
11033tVOS_CON_MODE hdd_get_conparam ( void )
11034{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011035#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011037#else
11038 return (tVOS_CON_MODE)curr_con_mode;
11039#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011040}
11041void hdd_set_conparam ( v_UINT_t newParam )
11042{
11043 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011044#ifndef MODULE
11045 curr_con_mode = con_mode;
11046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011047}
11048/**---------------------------------------------------------------------------
11049
11050 \brief hdd_softap_sta_deauth() - function
11051
11052 This to take counter measure to handle deauth req from HDD
11053
11054 \param - pAdapter - Pointer to the HDD
11055
11056 \param - enable - boolean value
11057
11058 \return - None
11059
11060 --------------------------------------------------------------------------*/
11061
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011062VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
11063 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070011064{
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011066 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070011067
11068 ENTER();
11069
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011070 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
11071 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011072
11073 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011074 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011075 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011076
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011077 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070011078
11079 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011080 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011081}
11082
11083/**---------------------------------------------------------------------------
11084
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011085 \brief hdd_del_all_sta() - function
11086
11087 This function removes all the stations associated on stopping AP/P2P GO.
11088
11089 \param - pAdapter - Pointer to the HDD
11090
11091 \return - None
11092
11093 --------------------------------------------------------------------------*/
11094
11095int hdd_del_all_sta(hdd_adapter_t *pAdapter)
11096{
11097 v_U16_t i;
11098 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011099 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11100 ptSapContext pSapCtx = NULL;
11101 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11102 if(pSapCtx == NULL){
11103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11104 FL("psapCtx is NULL"));
11105 return 1;
11106 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011107 ENTER();
11108
11109 hddLog(VOS_TRACE_LEVEL_INFO,
11110 "%s: Delete all STAs associated.",__func__);
11111 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11112 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
11113 )
11114 {
11115 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11116 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011117 if ((pSapCtx->aStaInfo[i].isUsed) &&
11118 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011119 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011120 struct tagCsrDelStaParams delStaParams;
11121
11122 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011123 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011124 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11125 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011126 &delStaParams);
11127 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011128 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011129 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011130 }
11131 }
11132 }
11133
11134 EXIT();
11135 return 0;
11136}
11137
11138/**---------------------------------------------------------------------------
11139
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 \brief hdd_softap_sta_disassoc() - function
11141
11142 This to take counter measure to handle deauth req from HDD
11143
11144 \param - pAdapter - Pointer to the HDD
11145
11146 \param - enable - boolean value
11147
11148 \return - None
11149
11150 --------------------------------------------------------------------------*/
11151
11152void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11153{
11154 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11155
11156 ENTER();
11157
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011158 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011159
11160 //Ignore request to disassoc bcmc station
11161 if( pDestMacAddress[0] & 0x1 )
11162 return;
11163
11164 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11165}
11166
11167void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11168{
11169 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11170
11171 ENTER();
11172
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011173 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011174
11175 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11176}
11177
Jeff Johnson295189b2012-06-20 16:38:30 -070011178/**---------------------------------------------------------------------------
11179 *
11180 * \brief hdd_get__concurrency_mode() -
11181 *
11182 *
11183 * \param - None
11184 *
11185 * \return - CONCURRENCY MODE
11186 *
11187 * --------------------------------------------------------------------------*/
11188tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11189{
11190 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11191 hdd_context_t *pHddCtx;
11192
11193 if (NULL != pVosContext)
11194 {
11195 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11196 if (NULL != pHddCtx)
11197 {
11198 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11199 }
11200 }
11201
11202 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011203 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 return VOS_STA;
11205}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011206v_BOOL_t
11207wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11208{
11209 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011210
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011211 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11212 if (pAdapter == NULL)
11213 {
11214 hddLog(VOS_TRACE_LEVEL_INFO,
11215 FL("GO doesn't exist"));
11216 return TRUE;
11217 }
11218 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11219 {
11220 hddLog(VOS_TRACE_LEVEL_INFO,
11221 FL("GO started"));
11222 return TRUE;
11223 }
11224 else
11225 /* wait till GO changes its interface to p2p device */
11226 hddLog(VOS_TRACE_LEVEL_INFO,
11227 FL("Del_bss called, avoid apps suspend"));
11228 return FALSE;
11229
11230}
Jeff Johnson295189b2012-06-20 16:38:30 -070011231/* Decide whether to allow/not the apps power collapse.
11232 * Allow apps power collapse if we are in connected state.
11233 * if not, allow only if we are in IMPS */
11234v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11235{
11236 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011237 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011238 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11240 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11241 hdd_adapter_t *pAdapter = NULL;
11242 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011243 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011244
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11246 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011247
Yathish9f22e662012-12-10 14:21:35 -080011248 concurrent_state = hdd_get_concurrency_mode();
11249
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011250 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11251 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11252 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011253#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011254
Yathish9f22e662012-12-10 14:21:35 -080011255 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011256 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011257 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11258 return TRUE;
11259#endif
11260
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 /*loop through all adapters. TBD fix for Concurrency */
11262 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11263 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11264 {
11265 pAdapter = pAdapterNode->pAdapter;
11266 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11267 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11268 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011269 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011270 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011271 && pmcState != STOPPED && pmcState != STANDBY &&
11272 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011273 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11274 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011276 if(pmcState == FULL_POWER &&
11277 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11278 {
11279 /*
11280 * When SCO indication comes from Coex module , host will
11281 * enter in to full power mode, but this should not prevent
11282 * apps processor power collapse.
11283 */
11284 hddLog(LOG1,
11285 FL("Allow apps power collapse"
11286 "even when sco indication is set"));
11287 return TRUE;
11288 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011289 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011290 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11291 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 return FALSE;
11293 }
11294 }
11295 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11296 pAdapterNode = pNext;
11297 }
11298 return TRUE;
11299}
11300
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011301/* Decides whether to send suspend notification to Riva
11302 * if any adapter is in BMPS; then it is required */
11303v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11304{
11305 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11306 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11307
11308 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11309 {
11310 return TRUE;
11311 }
11312 return FALSE;
11313}
11314
Jeff Johnson295189b2012-06-20 16:38:30 -070011315void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11316{
11317 switch(mode)
11318 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011319 case VOS_STA_MODE:
11320 case VOS_P2P_CLIENT_MODE:
11321 case VOS_P2P_GO_MODE:
11322 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011323 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011324 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 break;
11326 default:
11327 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011329 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11330 "Number of open sessions for mode %d = %d"),
11331 pHddCtx->concurrency_mode, mode,
11332 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011333}
11334
11335
11336void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11337{
11338 switch(mode)
11339 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011340 case VOS_STA_MODE:
11341 case VOS_P2P_CLIENT_MODE:
11342 case VOS_P2P_GO_MODE:
11343 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011344 pHddCtx->no_of_open_sessions[mode]--;
11345 if (!(pHddCtx->no_of_open_sessions[mode]))
11346 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 break;
11348 default:
11349 break;
11350 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011351 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11352 "Number of open sessions for mode %d = %d"),
11353 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11354
11355}
11356/**---------------------------------------------------------------------------
11357 *
11358 * \brief wlan_hdd_incr_active_session()
11359 *
11360 * This function increments the number of active sessions
11361 * maintained per device mode
11362 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11363 * Incase of SAP/P2P GO upon bss start it is incremented
11364 *
11365 * \param pHddCtx - HDD Context
11366 * \param mode - device mode
11367 *
11368 * \return - None
11369 *
11370 * --------------------------------------------------------------------------*/
11371void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11372{
11373 switch (mode) {
11374 case VOS_STA_MODE:
11375 case VOS_P2P_CLIENT_MODE:
11376 case VOS_P2P_GO_MODE:
11377 case VOS_STA_SAP_MODE:
11378 pHddCtx->no_of_active_sessions[mode]++;
11379 break;
11380 default:
11381 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11382 break;
11383 }
11384 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11385 mode,
11386 pHddCtx->no_of_active_sessions[mode]);
11387}
11388
11389/**---------------------------------------------------------------------------
11390 *
11391 * \brief wlan_hdd_decr_active_session()
11392 *
11393 * This function decrements the number of active sessions
11394 * maintained per device mode
11395 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11396 * Incase of SAP/P2P GO upon bss stop it is decremented
11397 *
11398 * \param pHddCtx - HDD Context
11399 * \param mode - device mode
11400 *
11401 * \return - None
11402 *
11403 * --------------------------------------------------------------------------*/
11404void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11405{
11406 switch (mode) {
11407 case VOS_STA_MODE:
11408 case VOS_P2P_CLIENT_MODE:
11409 case VOS_P2P_GO_MODE:
11410 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011411 if (pHddCtx->no_of_active_sessions[mode] > 0)
11412 pHddCtx->no_of_active_sessions[mode]--;
11413 else
11414 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11415 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011416 break;
11417 default:
11418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11419 break;
11420 }
11421 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11422 mode,
11423 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011424}
11425
Jeff Johnsone7245742012-09-05 17:12:55 -070011426/**---------------------------------------------------------------------------
11427 *
11428 * \brief wlan_hdd_restart_init
11429 *
11430 * This function initalizes restart timer/flag. An internal function.
11431 *
11432 * \param - pHddCtx
11433 *
11434 * \return - None
11435 *
11436 * --------------------------------------------------------------------------*/
11437
11438static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11439{
11440 /* Initialize */
11441 pHddCtx->hdd_restart_retries = 0;
11442 atomic_set(&pHddCtx->isRestartInProgress, 0);
11443 vos_timer_init(&pHddCtx->hdd_restart_timer,
11444 VOS_TIMER_TYPE_SW,
11445 wlan_hdd_restart_timer_cb,
11446 pHddCtx);
11447}
11448/**---------------------------------------------------------------------------
11449 *
11450 * \brief wlan_hdd_restart_deinit
11451 *
11452 * This function cleans up the resources used. An internal function.
11453 *
11454 * \param - pHddCtx
11455 *
11456 * \return - None
11457 *
11458 * --------------------------------------------------------------------------*/
11459
11460static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11461{
11462
11463 VOS_STATUS vos_status;
11464 /* Block any further calls */
11465 atomic_set(&pHddCtx->isRestartInProgress, 1);
11466 /* Cleanup */
11467 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11468 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011469 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011470 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11471 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011472 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011473
11474}
11475
11476/**---------------------------------------------------------------------------
11477 *
11478 * \brief wlan_hdd_framework_restart
11479 *
11480 * This function uses a cfg80211 API to start a framework initiated WLAN
11481 * driver module unload/load.
11482 *
11483 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11484 *
11485 *
11486 * \param - pHddCtx
11487 *
11488 * \return - VOS_STATUS_SUCCESS: Success
11489 * VOS_STATUS_E_EMPTY: Adapter is Empty
11490 * VOS_STATUS_E_NOMEM: No memory
11491
11492 * --------------------------------------------------------------------------*/
11493
11494static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11495{
11496 VOS_STATUS status = VOS_STATUS_SUCCESS;
11497 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011498 int len = (sizeof (struct ieee80211_mgmt));
11499 struct ieee80211_mgmt *mgmt = NULL;
11500
11501 /* Prepare the DEAUTH managment frame with reason code */
11502 mgmt = kzalloc(len, GFP_KERNEL);
11503 if(mgmt == NULL)
11504 {
11505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11506 "%s: memory allocation failed (%d bytes)", __func__, len);
11507 return VOS_STATUS_E_NOMEM;
11508 }
11509 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011510
11511 /* Iterate over all adapters/devices */
11512 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011513 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11514 {
11515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11516 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11517 goto end;
11518 }
11519
Jeff Johnsone7245742012-09-05 17:12:55 -070011520 do
11521 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011522 if(pAdapterNode->pAdapter &&
11523 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011524 {
11525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11526 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11527 pAdapterNode->pAdapter->dev->name,
11528 pAdapterNode->pAdapter->device_mode,
11529 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011530 /*
11531 * CFG80211 event to restart the driver
11532 *
11533 * 'cfg80211_send_unprot_deauth' sends a
11534 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11535 * of SME(Linux Kernel) state machine.
11536 *
11537 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11538 * the driver.
11539 *
11540 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11542 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11543#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011544 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011545#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011546 }
11547 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11548 pAdapterNode = pNext;
11549 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11550
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011551 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011552 /* Free the allocated management frame */
11553 kfree(mgmt);
11554
Jeff Johnsone7245742012-09-05 17:12:55 -070011555 /* Retry until we unload or reach max count */
11556 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11557 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11558
11559 return status;
11560
11561}
11562/**---------------------------------------------------------------------------
11563 *
11564 * \brief wlan_hdd_restart_timer_cb
11565 *
11566 * Restart timer callback. An internal function.
11567 *
11568 * \param - User data:
11569 *
11570 * \return - None
11571 *
11572 * --------------------------------------------------------------------------*/
11573
11574void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11575{
11576 hdd_context_t *pHddCtx = usrDataForCallback;
11577 wlan_hdd_framework_restart(pHddCtx);
11578 return;
11579
11580}
11581
11582
11583/**---------------------------------------------------------------------------
11584 *
11585 * \brief wlan_hdd_restart_driver
11586 *
11587 * This function sends an event to supplicant to restart the WLAN driver.
11588 *
11589 * This function is called from vos_wlanRestart.
11590 *
11591 * \param - pHddCtx
11592 *
11593 * \return - VOS_STATUS_SUCCESS: Success
11594 * VOS_STATUS_E_EMPTY: Adapter is Empty
11595 * VOS_STATUS_E_ALREADY: Request already in progress
11596
11597 * --------------------------------------------------------------------------*/
11598VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11599{
11600 VOS_STATUS status = VOS_STATUS_SUCCESS;
11601
11602 /* A tight check to make sure reentrancy */
11603 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11604 {
Mihir Shetefd528652014-06-23 19:07:50 +053011605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011606 "%s: WLAN restart is already in progress", __func__);
11607
11608 return VOS_STATUS_E_ALREADY;
11609 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011610 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011611#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011612 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011613#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011614
Jeff Johnsone7245742012-09-05 17:12:55 -070011615 return status;
11616}
11617
Mihir Shetee1093ba2014-01-21 20:13:32 +053011618/**---------------------------------------------------------------------------
11619 *
11620 * \brief wlan_hdd_init_channels
11621 *
11622 * This function is used to initialize the channel list in CSR
11623 *
11624 * This function is called from hdd_wlan_startup
11625 *
11626 * \param - pHddCtx: HDD context
11627 *
11628 * \return - VOS_STATUS_SUCCESS: Success
11629 * VOS_STATUS_E_FAULT: Failure reported by SME
11630
11631 * --------------------------------------------------------------------------*/
11632static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11633{
11634 eHalStatus status;
11635
11636 status = sme_InitChannels(pHddCtx->hHal);
11637 if (HAL_STATUS_SUCCESS(status))
11638 {
11639 return VOS_STATUS_SUCCESS;
11640 }
11641 else
11642 {
11643 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11644 __func__, status);
11645 return VOS_STATUS_E_FAULT;
11646 }
11647}
11648
Mihir Shete04206452014-11-20 17:50:58 +053011649#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011650VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011651{
11652 eHalStatus status;
11653
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011654 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011655 if (HAL_STATUS_SUCCESS(status))
11656 {
11657 return VOS_STATUS_SUCCESS;
11658 }
11659 else
11660 {
11661 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11662 __func__, status);
11663 return VOS_STATUS_E_FAULT;
11664 }
11665}
Mihir Shete04206452014-11-20 17:50:58 +053011666#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011667/*
11668 * API to find if there is any STA or P2P-Client is connected
11669 */
11670VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11671{
11672 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11673}
Jeff Johnsone7245742012-09-05 17:12:55 -070011674
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011675
11676/*
11677 * API to find if the firmware will send logs using DXE channel
11678 */
11679v_U8_t hdd_is_fw_logging_enabled(void)
11680{
11681 hdd_context_t *pHddCtx;
11682
11683 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11684 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11685
Sachin Ahuja084313e2015-05-21 17:57:10 +053011686 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011687}
11688
Agarwal Ashish57e84372014-12-05 18:26:53 +053011689/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011690 * API to find if the firmware will send trace logs using DXE channel
11691 */
11692v_U8_t hdd_is_fw_ev_logging_enabled(void)
11693{
11694 hdd_context_t *pHddCtx;
11695
11696 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11697 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11698
11699 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11700}
11701/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011702 * API to find if there is any session connected
11703 */
11704VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11705{
11706 return sme_is_any_session_connected(pHddCtx->hHal);
11707}
11708
11709
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011710int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11711{
11712 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11713 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011714 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011715 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011716
11717 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011718 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011719 if (pScanInfo->mScanPending)
11720 {
c_hpothua3d45d52015-01-05 14:11:17 +053011721 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11722 eCSR_SCAN_ABORT_DEFAULT);
11723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11724 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011725
c_hpothua3d45d52015-01-05 14:11:17 +053011726 /* If there is active scan command lets wait for the completion else
11727 * there is no need to wait as scan command might be in the SME pending
11728 * command list.
11729 */
11730 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11731 {
c_hpothua3d45d52015-01-05 14:11:17 +053011732 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011733 &pScanInfo->abortscan_event_var,
11734 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011735 if (0 >= status)
11736 {
11737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011738 "%s: Timeout or Interrupt occurred while waiting for abort"
11739 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011740 return -ETIMEDOUT;
11741 }
11742 }
11743 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11744 {
11745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11746 FL("hdd_abort_mac_scan failed"));
11747 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011748 }
11749 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011750 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011751}
11752
c_hpothu225aa7c2014-10-22 17:45:13 +053011753VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11754{
11755 hdd_adapter_t *pAdapter;
11756 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11757 VOS_STATUS vosStatus;
11758
11759 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11760 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11761 {
11762 pAdapter = pAdapterNode->pAdapter;
11763 if (NULL != pAdapter)
11764 {
11765 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11766 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11767 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11768 {
11769 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11770 pAdapter->device_mode);
11771 if (VOS_STATUS_SUCCESS !=
11772 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11773 {
11774 hddLog(LOGE, FL("failed to abort ROC"));
11775 return VOS_STATUS_E_FAILURE;
11776 }
11777 }
11778 }
11779 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11780 pAdapterNode = pNext;
11781 }
11782 return VOS_STATUS_SUCCESS;
11783}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011784
Mihir Shete0be28772015-02-17 18:42:14 +053011785hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11786{
11787 hdd_adapter_t *pAdapter;
11788 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11789 hdd_cfg80211_state_t *cfgState;
11790 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11791 VOS_STATUS vosStatus;
11792
11793 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11794 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11795 {
11796 pAdapter = pAdapterNode->pAdapter;
11797 if (NULL != pAdapter)
11798 {
11799 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11800 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11801 if (pRemainChanCtx)
11802 break;
11803 }
11804 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11805 pAdapterNode = pNext;
11806 }
11807 return pRemainChanCtx;
11808}
11809
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011810/**
11811 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11812 *
11813 * @pHddCtx: HDD context within host driver
11814 * @dfsScanMode: dfsScanMode passed from ioctl
11815 *
11816 */
11817
11818VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11819 tANI_U8 dfsScanMode)
11820{
11821 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11822 hdd_adapter_t *pAdapter;
11823 VOS_STATUS vosStatus;
11824 hdd_station_ctx_t *pHddStaCtx;
11825 eHalStatus status = eHAL_STATUS_SUCCESS;
11826
11827 if(!pHddCtx)
11828 {
11829 hddLog(LOGE, FL("HDD context is Null"));
11830 return eHAL_STATUS_FAILURE;
11831 }
11832
11833 if (pHddCtx->scan_info.mScanPending)
11834 {
11835 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11836 pHddCtx->scan_info.sessionId);
11837 hdd_abort_mac_scan(pHddCtx,
11838 pHddCtx->scan_info.sessionId,
11839 eCSR_SCAN_ABORT_DEFAULT);
11840 }
11841
11842 if (!dfsScanMode)
11843 {
11844 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11845 while ((NULL != pAdapterNode) &&
11846 (VOS_STATUS_SUCCESS == vosStatus))
11847 {
11848 pAdapter = pAdapterNode->pAdapter;
11849
11850 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11851 {
11852 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11853
11854 if(!pHddStaCtx)
11855 {
11856 hddLog(LOGE, FL("HDD STA context is Null"));
11857 return eHAL_STATUS_FAILURE;
11858 }
11859
11860 /* if STA is already connected on DFS channel,
11861 disconnect immediately*/
11862 if (hdd_connIsConnected(pHddStaCtx) &&
11863 (NV_CHANNEL_DFS ==
11864 vos_nv_getChannelEnabledState(
11865 pHddStaCtx->conn_info.operationChannel)))
11866 {
11867 status = sme_RoamDisconnect(pHddCtx->hHal,
11868 pAdapter->sessionId,
11869 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11870 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11871 "sme_RoamDisconnect returned with status: %d"
11872 "for sessionid: %d"), pHddStaCtx->conn_info.
11873 operationChannel, status, pAdapter->sessionId);
11874 }
11875 }
11876
11877 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11878 &pNext);
11879 pAdapterNode = pNext;
11880 }
11881 }
11882
11883 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11884 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11885 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11886
11887 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11888 if (!HAL_STATUS_SUCCESS(status))
11889 {
11890 hddLog(LOGE,
11891 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11892 return status;
11893 }
11894
11895 return status;
11896}
11897
Nirav Shah7e3c8132015-06-22 23:51:42 +053011898static int hdd_log2_ceil(unsigned value)
11899{
11900 /* need to switch to unsigned math so that negative values
11901 * will right-shift towards 0 instead of -1
11902 */
11903 unsigned tmp = value;
11904 int log2 = -1;
11905
11906 if (value == 0)
11907 return 0;
11908
11909 while (tmp) {
11910 log2++;
11911 tmp >>= 1;
11912 }
11913 if (1U << log2 != value)
11914 log2++;
11915
11916 return log2;
11917}
11918
11919/**
11920 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11921 * @pAdapter: adapter handle
11922 *
11923 * Return: vos status
11924 */
11925VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11926{
11927 int hash_elem, log2, i;
11928
11929 spin_lock_bh( &pAdapter->sta_hash_lock);
11930 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11931 spin_unlock_bh( &pAdapter->sta_hash_lock);
11932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11933 "%s: hash already attached for session id %d",
11934 __func__, pAdapter->sessionId);
11935 return VOS_STATUS_SUCCESS;
11936 }
11937 spin_unlock_bh( &pAdapter->sta_hash_lock);
11938
11939 hash_elem = WLAN_MAX_STA_COUNT;
11940 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11941 log2 = hdd_log2_ceil(hash_elem);
11942 hash_elem = 1 << log2;
11943
11944 pAdapter->sta_id_hash.mask = hash_elem - 1;
11945 pAdapter->sta_id_hash.idx_bits = log2;
11946 pAdapter->sta_id_hash.bins =
11947 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11948 if (!pAdapter->sta_id_hash.bins) {
11949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11950 "%s: malloc failed for session %d",
11951 __func__, pAdapter->sessionId);
11952 return VOS_STATUS_E_NOMEM;
11953 }
11954
11955 for (i = 0; i < hash_elem; i++)
11956 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11957
11958 spin_lock_bh( &pAdapter->sta_hash_lock);
11959 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11960 spin_unlock_bh( &pAdapter->sta_hash_lock);
11961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11962 "%s: Station ID Hash attached for session id %d",
11963 __func__, pAdapter->sessionId);
11964
11965 return VOS_STATUS_SUCCESS;
11966}
11967
11968/**
11969 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11970 * @pAdapter: adapter handle
11971 *
11972 * Return: vos status
11973 */
11974VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11975{
11976 int hash_elem, i;
11977 v_SIZE_t size;
11978
11979 spin_lock_bh( &pAdapter->sta_hash_lock);
11980 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11981 spin_unlock_bh( &pAdapter->sta_hash_lock);
11982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11983 "%s: hash not initialized for session id %d",
11984 __func__, pAdapter->sessionId);
11985 return VOS_STATUS_SUCCESS;
11986 }
11987
11988 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11989 spin_unlock_bh( &pAdapter->sta_hash_lock);
11990
11991 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11992
11993 /* free all station info*/
11994 for (i = 0; i < hash_elem; i++) {
11995 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11996 if (size != 0) {
11997 VOS_STATUS status;
11998 hdd_staid_hash_node_t *sta_info_node = NULL;
11999 hdd_staid_hash_node_t *next_node = NULL;
12000 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
12001 (hdd_list_node_t**) &sta_info_node );
12002
12003 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12004 {
12005 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
12006 &sta_info_node->node);
12007 vos_mem_free(sta_info_node);
12008
12009 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
12010 (hdd_list_node_t*)sta_info_node,
12011 (hdd_list_node_t**)&next_node);
12012 sta_info_node = next_node;
12013 }
12014 }
12015 }
12016
12017 vos_mem_free(pAdapter->sta_id_hash.bins);
12018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12019 "%s: Station ID Hash detached for session id %d",
12020 __func__, pAdapter->sessionId);
12021 return VOS_STATUS_SUCCESS;
12022}
12023
12024/**
12025 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
12026 * @pAdapter: adapter handle
12027 * @mac_addr_in: input mac address
12028 *
12029 * Return: index derived from mac address
12030 */
12031int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
12032 v_MACADDR_t *mac_addr_in)
12033{
12034 uint16 index;
12035 struct hdd_align_mac_addr_t * mac_addr =
12036 (struct hdd_align_mac_addr_t *)mac_addr_in;
12037
12038 index = mac_addr->bytes_ab ^
12039 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
12040 index ^= index >> pAdapter->sta_id_hash.idx_bits;
12041 index &= pAdapter->sta_id_hash.mask;
12042 return index;
12043}
12044
12045/**
12046 * hdd_sta_id_hash_add_entry() - add entry in hash
12047 * @pAdapter: adapter handle
12048 * @sta_id: station id
12049 * @mac_addr: mac address
12050 *
12051 * Return: vos status
12052 */
12053VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
12054 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12055{
12056 uint16 index;
12057 hdd_staid_hash_node_t *sta_info_node = NULL;
12058
Nirav Shah7e3c8132015-06-22 23:51:42 +053012059 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12060 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
12061 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053012062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12063 "%s: malloc failed", __func__);
12064 return VOS_STATUS_E_NOMEM;
12065 }
12066
12067 sta_info_node->sta_id = sta_id;
12068 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
12069
Nirav Shah303ed5c2015-08-24 10:29:25 +053012070 spin_lock_bh( &pAdapter->sta_hash_lock);
12071 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12072 spin_unlock_bh( &pAdapter->sta_hash_lock);
12073 vos_mem_free(sta_info_node);
12074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12075 "%s: hash is not initialized for session id %d",
12076 __func__, pAdapter->sessionId);
12077 return VOS_STATUS_E_FAILURE;
12078 }
12079
Nirav Shah7e3c8132015-06-22 23:51:42 +053012080 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
12081 (hdd_list_node_t*) sta_info_node );
12082 spin_unlock_bh( &pAdapter->sta_hash_lock);
12083 return VOS_STATUS_SUCCESS;
12084}
12085
12086/**
12087 * hdd_sta_id_hash_remove_entry() - remove entry from hash
12088 * @pAdapter: adapter handle
12089 * @sta_id: station id
12090 * @mac_addr: mac address
12091 *
12092 * Return: vos status
12093 */
12094VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
12095 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12096{
12097 uint16 index;
12098 VOS_STATUS status;
12099 hdd_staid_hash_node_t *sta_info_node = NULL;
12100 hdd_staid_hash_node_t *next_node = NULL;
12101
12102 spin_lock_bh( &pAdapter->sta_hash_lock);
12103 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12104 spin_unlock_bh( &pAdapter->sta_hash_lock);
12105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12106 "%s: hash is not initialized for session id %d",
12107 __func__, pAdapter->sessionId);
12108 return VOS_STATUS_E_FAILURE;
12109 }
12110
12111 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12112 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12113 (hdd_list_node_t**) &sta_info_node );
12114
12115 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12116 {
12117 if (sta_info_node->sta_id == sta_id) {
12118 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
12119 &sta_info_node->node);
12120 vos_mem_free(sta_info_node);
12121 break;
12122 }
12123 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12124 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12125 sta_info_node = next_node;
12126 }
12127 spin_unlock_bh( &pAdapter->sta_hash_lock);
12128 return status;
12129}
12130
12131/**
12132 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12133 * @pAdapter: adapter handle
12134 * @mac_addr_in: mac address
12135 *
12136 * Return: station id
12137 */
12138int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12139 v_MACADDR_t *mac_addr_in)
12140{
12141 uint8 is_found = 0;
12142 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12143 uint16 index;
12144 VOS_STATUS status;
12145 hdd_staid_hash_node_t *sta_info_node = NULL;
12146 hdd_staid_hash_node_t *next_node = NULL;
12147
12148 spin_lock_bh( &pAdapter->sta_hash_lock);
12149 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12150 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053012151 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053012152 FL("hash is not initialized for session id %d"),
12153 pAdapter->sessionId);
12154 return HDD_WLAN_INVALID_STA_ID;
12155 }
12156
12157 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12158 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12159 (hdd_list_node_t**) &sta_info_node );
12160
12161 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12162 {
12163 if (vos_mem_compare(&sta_info_node->mac_addr,
12164 mac_addr_in, sizeof(v_MACADDR_t))) {
12165 is_found = 1;
12166 sta_id = sta_info_node->sta_id;
12167 break;
12168 }
12169 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12170 (hdd_list_node_t*)sta_info_node,
12171 (hdd_list_node_t**)&next_node);
12172 sta_info_node = next_node;
12173 }
12174 spin_unlock_bh( &pAdapter->sta_hash_lock);
12175 return sta_id;
12176}
12177
c_manjeecfd1efb2015-09-25 19:32:34 +053012178/*FW memory dump feature*/
12179/**
12180 * This structure hold information about the /proc file
12181 *
12182 */
12183static struct proc_dir_entry *proc_file, *proc_dir;
12184
12185/**
12186 * memdump_read() - perform read operation in memory dump proc file
12187 *
12188 * @file - handle for the proc file.
12189 * @buf - pointer to user space buffer.
12190 * @count - number of bytes to be read.
12191 * @pos - offset in the from buffer.
12192 *
12193 * This function performs read operation for the memory dump proc file.
12194 *
12195 * Return: number of bytes read on success, error code otherwise.
12196 */
12197static ssize_t memdump_read(struct file *file, char __user *buf,
12198 size_t count, loff_t *pos)
12199{
12200 int status;
12201 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
12202 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053012203 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053012204 ENTER();
12205
12206 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
12207 status = wlan_hdd_validate_context(hdd_ctx);
12208 if (0 != status) {
12209 return -EINVAL;
12210 }
12211
12212 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
12213 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
12214 return -EINVAL;
12215 }
12216
12217 /* run fs_read_handler in an atomic context*/
12218 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053012219 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
12220 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053012221 {
12222 /*Free the fwr mem dump buffer */
12223 wlan_free_fwr_mem_dump_buffer();
12224 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053012225 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053012226 }
12227 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
12228 vos_ssr_unprotect(__func__);
12229 EXIT();
12230 return ret_count;
12231}
12232
12233/**
12234 * struct memdump_fops - file operations for memory dump feature
12235 * @read - read function for memory dump operation.
12236 *
12237 * This structure initialize the file operation handle for memory
12238 * dump feature
12239 */
12240static const struct file_operations memdump_fops = {
12241 read: memdump_read
12242};
12243
12244/*
12245* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
12246* To be passed by HDD to WDA and called upon receiving of response
12247* from firmware
12248* @fwMemDumpReqContext : memory dump request context
12249* @dump_rsp : dump response from HAL
12250* Returns none
12251*/
12252void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
12253 tAniFwrDumpRsp *dump_rsp)
12254{
c_manjeef1495642015-10-13 18:35:01 +053012255 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053012256
c_manjeef1495642015-10-13 18:35:01 +053012257 ENTER();
12258 spin_lock(&hdd_context_lock);
12259 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
12260 spin_unlock(&hdd_context_lock);
12261 return;
12262 }
12263 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053012264 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053012265 hddLog(LOGE, FL("fw dump request declined by fwr"));
12266 //set the request completion variable
12267 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053012268 //Free the allocated fwr dump
12269 wlan_free_fwr_mem_dump_buffer();
12270 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053012271 }
c_manjeef1495642015-10-13 18:35:01 +053012272 else {
12273 hddLog(LOG1, FL("fw dump request accepted by fwr"));
12274 /* register the HDD callback which will be called by SVC */
12275 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
12276 }
12277 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012278 EXIT();
12279
12280}
12281
12282/**
12283 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
12284 *
12285 * This function removes file/dir under proc file system that was
12286 * processing firmware memory dump
12287 *
12288 * Return: None
12289 */
12290static void memdump_procfs_remove(void)
12291{
12292 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12293 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
12294 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12295 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12296 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
12297}
12298
12299/**
12300 * memdump_procfs_init() - Initialize procfs for memory dump
12301 *
12302 * @vos_ctx - Global vos context.
12303 *
12304 * This function create file under proc file system to be used later for
12305 * processing firmware memory dump
12306 *
12307 * Return: 0 on success, error code otherwise.
12308 */
12309static int memdump_procfs_init(void *vos_ctx)
12310{
12311 hdd_context_t *hdd_ctx;
12312
12313 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12314 if (!hdd_ctx) {
12315 hddLog(LOGE , FL("Invalid HDD context"));
12316 return -EINVAL;
12317 }
12318
12319 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
12320 if (proc_dir == NULL) {
12321 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12322 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12323 PROCFS_MEMDUMP_DIR);
12324 return -ENOMEM;
12325 }
12326
12327 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
12328 S_IRUSR | S_IWUSR, proc_dir,
12329 &memdump_fops, hdd_ctx);
12330 if (proc_file == NULL) {
12331 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12332 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12333 PROCFS_MEMDUMP_NAME);
12334 return -ENOMEM;
12335 }
12336
12337 hddLog(LOG1 , FL("/proc/%s/%s created"),
12338 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12339
12340 return 0;
12341}
12342
12343/**
12344 * memdump_init() - Initialization function for memory dump feature
12345 *
12346 * This function creates proc file for memdump feature and registers
12347 * HDD callback function with SME.
12348 *
12349 * Return - 0 on success, error otherwise
12350 */
12351int memdump_init(void)
12352{
12353 hdd_context_t *hdd_ctx;
12354 void *vos_ctx;
12355 int status = 0;
12356
12357 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12358 if (!vos_ctx) {
12359 hddLog(LOGE, FL("Invalid VOS context"));
12360 return -EINVAL;
12361 }
12362
12363 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12364 if (!hdd_ctx) {
12365 hddLog(LOGE , FL("Invalid HDD context"));
12366 return -EINVAL;
12367 }
12368
12369 status = memdump_procfs_init(vos_ctx);
12370 if (status) {
12371 hddLog(LOGE , FL("Failed to create proc file"));
12372 return status;
12373 }
12374
12375 return 0;
12376}
12377
12378/**
12379 * memdump_deinit() - De initialize memdump feature
12380 *
12381 * This function removes proc file created for memdump feature.
12382 *
12383 * Return: None
12384 */
12385int memdump_deinit(void)
12386{
12387 hdd_context_t *hdd_ctx;
12388 void *vos_ctx;
12389
12390 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12391 if (!vos_ctx) {
12392 hddLog(LOGE, FL("Invalid VOS context"));
12393 return -EINVAL;
12394 }
12395
12396 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12397 if(!hdd_ctx) {
12398 hddLog(LOGE , FL("Invalid HDD context"));
12399 return -EINVAL;
12400 }
12401
12402 memdump_procfs_remove();
12403 return 0;
12404}
12405
12406/**
12407 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
12408 * Return: HAL status
12409 */
12410
12411int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
12412{
12413 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053012414 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012415 eHalStatus status = eHAL_STATUS_FAILURE;
12416 int ret=0;
12417 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053012418
c_manjeecfd1efb2015-09-25 19:32:34 +053012419 /*Check whether a dump request is already going on
12420 *Caution this function will free previously held memory if new dump request is allowed*/
12421 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
12422 hddLog(LOGE, FL("Fw memdump already in progress"));
12423 return -EBUSY;
12424 }
12425 //Allocate memory for fw mem dump buffer
12426 ret = wlan_fwr_mem_dump_buffer_allocation();
12427 if(ret == -EFAULT)
12428 {
12429 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
12430 return ret;
12431 }
12432 if (0 != ret) {
12433 hddLog(LOGE, FL("Fwr mem Allocation failed"));
12434 return -ENOMEM;
12435 }
c_manjeef1495642015-10-13 18:35:01 +053012436 init_completion(&fw_mem_dump_ctx.req_completion);
12437 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
12438 fw_mem_dump_ctx.status = false;
12439
c_manjeecfd1efb2015-09-25 19:32:34 +053012440 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053012441 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012442 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
12443 if(eHAL_STATUS_SUCCESS != status)
12444 {
12445 hddLog(VOS_TRACE_LEVEL_ERROR,
12446 "%s: fw_mem_dump_req failed ", __func__);
12447 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053012448 ret = -EFAULT;
12449 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053012450 }
c_manjeef1495642015-10-13 18:35:01 +053012451 /*wait for fw mem dump completion to send event to userspace*/
12452 ret = wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
12453 if (0 >= ret )
12454 {
12455 hddLog(VOS_TRACE_LEVEL_ERROR,
12456 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
12457 }
12458cleanup:
12459 spin_lock(&hdd_context_lock);
12460 fw_mem_dump_ctx.magic = 0;
12461 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012462
c_manjeef1495642015-10-13 18:35:01 +053012463 EXIT();
12464 return fw_mem_dump_ctx.status;
12465}
12466
12467/**
12468 * HDD callback which will be called by SVC to indicate mem dump completion.
12469 */
12470void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
12471{
12472 if (!pHddFwMemDumpCtx) {
12473 hddLog(VOS_TRACE_LEVEL_ERROR,
12474 "%s: HDD context not valid ", __func__);
12475 return;
12476 }
12477 spin_lock(&hdd_context_lock);
12478 /* check the req magic and set status */
12479 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
12480 {
12481 pHddFwMemDumpCtx->status = true;
12482 //signal the completion
12483 complete(&(pHddFwMemDumpCtx->req_completion));
12484 }
12485 else
12486 {
12487 hddLog(VOS_TRACE_LEVEL_ERROR,
12488 "%s: fw mem dump request possible timeout ", __func__);
12489 }
12490 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012491}
12492
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012493void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
12494{
12495 if (NULL == pAdapter)
12496 {
12497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
12498 return;
12499 }
12500 init_completion(&pAdapter->session_open_comp_var);
12501 init_completion(&pAdapter->session_close_comp_var);
12502 init_completion(&pAdapter->disconnect_comp_var);
12503 init_completion(&pAdapter->linkup_event_var);
12504 init_completion(&pAdapter->cancel_rem_on_chan_var);
12505 init_completion(&pAdapter->rem_on_chan_ready_event);
12506 init_completion(&pAdapter->pno_comp_var);
12507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12508 init_completion(&pAdapter->offchannel_tx_event);
12509#endif
12510 init_completion(&pAdapter->tx_action_cnf_event);
12511#ifdef FEATURE_WLAN_TDLS
12512 init_completion(&pAdapter->tdls_add_station_comp);
12513 init_completion(&pAdapter->tdls_del_station_comp);
12514 init_completion(&pAdapter->tdls_mgmt_comp);
12515 init_completion(&pAdapter->tdls_link_establish_req_comp);
12516#endif
12517
12518#ifdef WLAN_FEATURE_RMC
12519 init_completion(&pAdapter->ibss_peer_info_comp);
12520#endif /* WLAN_FEATURE_RMC */
12521 init_completion(&pAdapter->ula_complete);
12522 init_completion(&pAdapter->change_country_code);
12523
12524#ifdef FEATURE_WLAN_BATCH_SCAN
12525 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
12526 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
12527#endif
12528
12529 return;
12530}
c_manjeecfd1efb2015-09-25 19:32:34 +053012531
12532
Jeff Johnson295189b2012-06-20 16:38:30 -070012533//Register the module init/exit functions
12534module_init(hdd_module_init);
12535module_exit(hdd_module_exit);
12536
12537MODULE_LICENSE("Dual BSD/GPL");
12538MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12539MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12540
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012541module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12542 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012543
Jeff Johnson76052702013-04-16 13:55:05 -070012544module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012545 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012546
12547module_param(enable_dfs_chan_scan, int,
12548 S_IRUSR | S_IRGRP | S_IROTH);
12549
12550module_param(enable_11d, int,
12551 S_IRUSR | S_IRGRP | S_IROTH);
12552
12553module_param(country_code, charp,
12554 S_IRUSR | S_IRGRP | S_IROTH);