blob: 1097bc5445a8718d920d409474ba46022b4eb2bb [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar8b373292014-01-08 20:36:55 -08002 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*========================================================================
43
44 \file wlan_hdd_main.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 04/5/09 Shailender Created module.
69 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
70 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
71 ==========================================================================*/
72
73/*--------------------------------------------------------------------------
74 Include Files
75 ------------------------------------------------------------------------*/
76//#include <wlan_qct_driver.h>
77#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070078#include <vos_api.h>
79#include <vos_sched.h>
80#include <vos_power.h>
81#include <linux/etherdevice.h>
82#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#ifdef ANI_BUS_TYPE_PLATFORM
84#include <linux/wcnss_wlan.h>
85#endif //ANI_BUS_TYPE_PLATFORM
86#ifdef ANI_BUS_TYPE_PCI
87#include "wcnss_wlan.h"
88#endif /* ANI_BUS_TYPE_PCI */
89#include <wlan_hdd_tx_rx.h>
90#include <palTimer.h>
91#include <wniApi.h>
92#include <wlan_nlink_srv.h>
93#include <wlan_btc_svc.h>
94#include <wlan_hdd_cfg.h>
95#include <wlan_ptt_sock_svc.h>
96#include <wlan_hdd_wowl.h>
97#include <wlan_hdd_misc.h>
98#include <wlan_hdd_wext.h>
99#ifdef WLAN_BTAMP_FEATURE
100#include <bap_hdd_main.h>
101#include <bapInternal.h>
102#endif // WLAN_BTAMP_FEATURE
103
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include <linux/wireless.h>
105#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +0530106#include <linux/inetdevice.h>
107#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include "wlan_hdd_cfg80211.h"
109#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700111int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include "sapApi.h"
113#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700114#include <linux/ctype.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include <mach/subsystem_restart.h>
116#include <wlan_hdd_hostapd.h>
117#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "wlan_hdd_dev_pwr.h"
120#ifdef WLAN_BTAMP_FEATURE
121#include "bap_hdd_misc.h"
122#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700123#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700124#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800125#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530126#ifdef FEATURE_WLAN_TDLS
127#include "wlan_hdd_tdls.h"
128#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700129#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700130
131#ifdef MODULE
132#define WLAN_MODULE_NAME module_name(THIS_MODULE)
133#else
134#define WLAN_MODULE_NAME "wlan"
135#endif
136
137#ifdef TIMER_MANAGER
138#define TIMER_MANAGER_STR " +TIMER_MANAGER"
139#else
140#define TIMER_MANAGER_STR ""
141#endif
142
143#ifdef MEMORY_DEBUG
144#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
145#else
146#define MEMORY_DEBUG_STR ""
147#endif
148
149/* the Android framework expects this param even though we don't use it */
150#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700151static char fwpath_buffer[BUF_LEN];
152static struct kparam_string fwpath = {
153 .string = fwpath_buffer,
154 .maxlen = BUF_LEN,
155};
Arif Hussain66559122013-11-21 10:11:40 -0800156
157static char *country_code;
158static int enable_11d = -1;
159static int enable_dfs_chan_scan = -1;
160
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700161#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700162static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164
Jeff Johnsone7245742012-09-05 17:12:55 -0700165/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800166 * spinlock for synchronizing asynchronous request/response
167 * (full description of use in wlan_hdd_main.h)
168 */
169DEFINE_SPINLOCK(hdd_context_lock);
170
171/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700172 * The rate at which the driver sends RESTART event to supplicant
173 * once the function 'vos_wlanRestart()' is called
174 *
175 */
176#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
177#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700178
179/*
180 * Size of Driver command strings from upper layer
181 */
182#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
183#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
184
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700185#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
186#define TID_MIN_VALUE 0
187#define TID_MAX_VALUE 15
188static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
189 tAniTrafStrmMetrics* pTsmMetrics);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -0800190static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
191 tCsrCcxBeaconReq *pCcxBcnReq);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700192#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
193
Srinivas Girigowda4081bb12014-01-06 17:12:58 -0800194#define WLAN_PRIV_DATA_MAX_LEN 4096
195
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196/*
197 * Driver miracast parameters 0-Disabled
198 * 1-Source, 2-Sink
199 */
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
202
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800203#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700204static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700206/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700207static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700208
209//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700210static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
211static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
212static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
213void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800214void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700215
Jeff Johnson295189b2012-06-20 16:38:30 -0700216v_U16_t hdd_select_queue(struct net_device *dev,
217 struct sk_buff *skb);
218
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);
Amar Singhal4c723bd2013-03-25 18:14:15 -0700224int isWDresetInProgress(void);
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226extern int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
Amar Singhal0a402232013-10-11 20:57:16 -0700227
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
229void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
230static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700231static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
232 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
233 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700234static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
235 tANI_U8 *pTargetApBssid,
236 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800237#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700238#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
239VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
240#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
241
Jeff Johnson295189b2012-06-20 16:38:30 -0700242static int hdd_netdev_notifier_call(struct notifier_block * nb,
243 unsigned long state,
244 void *ndev)
245{
246 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700248 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700249#ifdef WLAN_BTAMP_FEATURE
250 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700251#endif
252
253 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700254 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700255 (strncmp(dev->name, "p2p", 3)))
256 return NOTIFY_DONE;
257
258 if (isWDresetInProgress())
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 return NOTIFY_DONE;
260
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700262 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700263
Jeff Johnson27cee452013-03-27 11:10:24 -0700264 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800266 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 VOS_ASSERT(0);
268 return NOTIFY_DONE;
269 }
270
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
272 if (NULL == pHddCtx)
273 {
274 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
275 VOS_ASSERT(0);
276 return NOTIFY_DONE;
277 }
278
279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
280 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
282 switch (state) {
283 case NETDEV_REGISTER:
284 break;
285
286 case NETDEV_UNREGISTER:
287 break;
288
289 case NETDEV_UP:
290 break;
291
292 case NETDEV_DOWN:
293 break;
294
295 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700296 if(TRUE == pAdapter->isLinkUpSvcNeeded)
297 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 break;
299
300 case NETDEV_GOING_DOWN:
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700301 if( pHddCtx->scan_info.mScanPending != FALSE )
Jeff Johnson295189b2012-06-20 16:38:30 -0700302 {
303 int result;
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800304 INIT_COMPLETION(pHddCtx->scan_info.abortscan_event_var);
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +0530305 hdd_abort_mac_scan(pAdapter->pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 result = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -0800307 &pHddCtx->scan_info.abortscan_event_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
309 if(!result)
310 {
311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson902c9832012-12-10 14:28:09 -0800312 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700313 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 }
315 }
316 else
317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700319 "%s: Scan is not Pending from user" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 }
321#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 status = WLANBAP_StopAmp();
324 if(VOS_STATUS_SUCCESS != status )
325 {
326 pHddCtx->isAmpAllowed = VOS_TRUE;
327 hddLog(VOS_TRACE_LEVEL_FATAL,
328 "%s: Failed to stop AMP", __func__);
329 }
330 else
331 {
332 //a state m/c implementation in PAL is TBD to avoid this delay
333 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700334 if ( pHddCtx->isAmpAllowed )
335 {
336 WLANBAP_DeregisterFromHCI();
337 pHddCtx->isAmpAllowed = VOS_FALSE;
338 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 }
340#endif //WLAN_BTAMP_FEATURE
341 break;
342
343 default:
344 break;
345 }
346
347 return NOTIFY_DONE;
348}
349
350struct notifier_block hdd_netdev_notifier = {
351 .notifier_call = hdd_netdev_notifier_call,
352};
353
354/*---------------------------------------------------------------------------
355 * Function definitions
356 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700357void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
358void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700359//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700360static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700361#ifndef MODULE
362/* current con_mode - used only for statically linked driver
363 * con_mode is changed by userspace to indicate a mode change which will
364 * result in calling the module exit and init functions. The module
365 * exit function will clean up based on the value of con_mode prior to it
366 * being changed by userspace. So curr_con_mode records the current con_mode
367 * for exit when con_mode becomes the next mode for init
368 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700369static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700370#endif
371
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800372/**---------------------------------------------------------------------------
373
374 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
375
376 Called immediately after the cfg.ini is read in order to configure
377 the desired trace levels.
378
379 \param - moduleId - module whose trace level is being configured
380 \param - bitmask - bitmask of log levels to be enabled
381
382 \return - void
383
384 --------------------------------------------------------------------------*/
385static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
386{
387 wpt_tracelevel level;
388
389 /* if the bitmask is the default value, then a bitmask was not
390 specified in cfg.ini, so leave the logging level alone (it
391 will remain at the "compiled in" default value) */
392 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
393 {
394 return;
395 }
396
397 /* a mask was specified. start by disabling all logging */
398 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
399
400 /* now cycle through the bitmask until all "set" bits are serviced */
401 level = VOS_TRACE_LEVEL_FATAL;
402 while (0 != bitmask)
403 {
404 if (bitmask & 1)
405 {
406 vos_trace_setValue(moduleId, level, 1);
407 }
408 level++;
409 bitmask >>= 1;
410 }
411}
412
413
Jeff Johnson295189b2012-06-20 16:38:30 -0700414/**---------------------------------------------------------------------------
415
416 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
417
418 Called immediately after the cfg.ini is read in order to configure
419 the desired trace levels in the WDI.
420
421 \param - moduleId - module whose trace level is being configured
422 \param - bitmask - bitmask of log levels to be enabled
423
424 \return - void
425
426 --------------------------------------------------------------------------*/
427static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
428{
429 wpt_tracelevel level;
430
431 /* if the bitmask is the default value, then a bitmask was not
432 specified in cfg.ini, so leave the logging level alone (it
433 will remain at the "compiled in" default value) */
434 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
435 {
436 return;
437 }
438
439 /* a mask was specified. start by disabling all logging */
440 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
441
442 /* now cycle through the bitmask until all "set" bits are serviced */
443 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
444 while (0 != bitmask)
445 {
446 if (bitmask & 1)
447 {
448 wpalTraceSetLevel(moduleId, level, 1);
449 }
450 level++;
451 bitmask >>= 1;
452 }
453}
Jeff Johnson295189b2012-06-20 16:38:30 -0700454
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530455/*
456 * FUNCTION: wlan_hdd_validate_context
457 * This function is used to check the HDD context
458 */
459int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
460{
461 ENTER();
462
463 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
464 {
465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
466 "%s: HDD context is Null", __func__);
467 return -ENODEV;
468 }
469
470 if (pHddCtx->isLogpInProgress)
471 {
472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
473 "%s: LOGP in Progress. Ignore!!!", __func__);
474 return -EAGAIN;
475 }
476
477 if (pHddCtx->isLoadUnloadInProgress)
478 {
479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
480 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
481 return -EAGAIN;
482 }
483 return 0;
484}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700485#ifdef CONFIG_ENABLE_LINUX_REG
486void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
487{
488 hdd_adapter_t *pAdapter = NULL;
489 hdd_station_ctx_t *pHddStaCtx = NULL;
490 eCsrPhyMode phyMode;
491 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700493 if (NULL == pHddCtx)
494 {
495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
496 "HDD Context is null !!");
497 return ;
498 }
499
500 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
501 if (NULL == pAdapter)
502 {
503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
504 "pAdapter is null !!");
505 return ;
506 }
507
508 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
509 if (NULL == pHddStaCtx)
510 {
511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
512 "pHddStaCtx is null !!");
513 return ;
514 }
515
516 cfg_param = pHddCtx->cfg_ini;
517 if (NULL == cfg_param)
518 {
519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
520 "cfg_params not available !!");
521 return ;
522 }
523
524 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
525
526 if (!pHddCtx->isVHT80Allowed)
527 {
528 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
529 (eCSR_DOT11_MODE_11ac == phyMode) ||
530 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
531 {
532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
533 "Setting phymode to 11n!!");
534 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
535 }
536 }
537 else
538 {
539 /*New country Supports 11ac as well resetting value back from .ini*/
540 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
541 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
542 return ;
543 }
544
545 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
546 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
547 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
548 {
549 VOS_STATUS vosStatus;
550
551 // need to issue a disconnect to CSR.
552 INIT_COMPLETION(pAdapter->disconnect_comp_var);
553 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
554 pAdapter->sessionId,
555 eCSR_DISCONNECT_REASON_UNSPECIFIED );
556
557 if (VOS_STATUS_SUCCESS == vosStatus)
558 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
559 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
560
561 }
562}
563#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530564void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
565{
566 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
567 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
568 hdd_config_t *cfg_param;
569 eCsrPhyMode phyMode;
570
571 if (NULL == pHddCtx)
572 {
573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
574 "HDD Context is null !!");
575 return ;
576 }
577
578 cfg_param = pHddCtx->cfg_ini;
579
580 if (NULL == cfg_param)
581 {
582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
583 "cfg_params not available !!");
584 return ;
585 }
586
587 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
588
589 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
590 {
591 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
592 (eCSR_DOT11_MODE_11ac == phyMode) ||
593 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
596 "Setting phymode to 11n!!");
597 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
598 }
599 }
600 else
601 {
602 /*New country Supports 11ac as well resetting value back from .ini*/
603 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
604 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
605 return ;
606 }
607
608 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
609 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
610 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
611 {
612 VOS_STATUS vosStatus;
613
614 // need to issue a disconnect to CSR.
615 INIT_COMPLETION(pAdapter->disconnect_comp_var);
616 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
617 pAdapter->sessionId,
618 eCSR_DISCONNECT_REASON_UNSPECIFIED );
619
620 if (VOS_STATUS_SUCCESS == vosStatus)
621 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
622 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
623
624 }
625}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700626#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530627
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700628void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
629{
630 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
631 hdd_config_t *cfg_param;
632
633 if (NULL == pHddCtx)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
636 "HDD Context is null !!");
637 return ;
638 }
639
640 cfg_param = pHddCtx->cfg_ini;
641
642 if (NULL == cfg_param)
643 {
644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
645 "cfg_params not available !!");
646 return ;
647 }
648
649 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
650 {
651 /*New country doesn't support DFS */
652 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
653 }
654 else
655 {
656 /*New country Supports DFS as well resetting value back from .ini*/
657 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
658 }
659
660}
661
Rajeev79dbe4c2013-10-05 11:03:42 +0530662#ifdef FEATURE_WLAN_BATCH_SCAN
663
664/**---------------------------------------------------------------------------
665
666 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
667 input string
668
669 This function extracts assigned integer from string in below format:
670 "STRING=10" : extracts integer 10 from this string
671
672 \param - pInPtr Pointer to input string
673 \param - base Base for string to int conversion(10 for decimal 16 for hex)
674 \param - pOutPtr Pointer to variable in which extracted integer needs to be
675 assigned
676 \param - pLastArg to tell whether it is last arguement in input string or
677 not
678
679 \return - NULL for failure cases
680 pointer to next arguement in input string for success cases
681 --------------------------------------------------------------------------*/
682static tANI_U8 *
683hdd_extract_assigned_int_from_str
684(
685 tANI_U8 *pInPtr,
686 tANI_U8 base,
687 tANI_U32 *pOutPtr,
688 tANI_U8 *pLastArg
689)
690{
691 int tempInt;
692 int v = 0;
693 char buf[32];
694 int val = 0;
695 *pLastArg = FALSE;
696
697 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
698 if (NULL == pInPtr)
699 {
700 return NULL;
701 }
702
703 pInPtr++;
704
705 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
706
707 val = sscanf(pInPtr, "%32s ", buf);
708 if (val < 0 && val > strlen(pInPtr))
709 {
710 return NULL;
711 }
712 pInPtr += val;
713 v = kstrtos32(buf, base, &tempInt);
714 if (v < 0)
715 {
716 return NULL;
717 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800718 if (tempInt < 0)
719 {
720 tempInt = 0;
721 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530722 *pOutPtr = tempInt;
723
724 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
725 if (NULL == pInPtr)
726 {
727 *pLastArg = TRUE;
728 return NULL;
729 }
730 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
731
732 return pInPtr;
733}
734
735/**---------------------------------------------------------------------------
736
737 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
738 input string
739
740 This function extracts assigned character from string in below format:
741 "STRING=A" : extracts char 'A' from this string
742
743 \param - pInPtr Pointer to input string
744 \param - pOutPtr Pointer to variable in which extracted char needs to be
745 assigned
746 \param - pLastArg to tell whether it is last arguement in input string or
747 not
748
749 \return - NULL for failure cases
750 pointer to next arguement in input string for success cases
751 --------------------------------------------------------------------------*/
752static tANI_U8 *
753hdd_extract_assigned_char_from_str
754(
755 tANI_U8 *pInPtr,
756 tANI_U8 *pOutPtr,
757 tANI_U8 *pLastArg
758)
759{
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 *pOutPtr = *pInPtr;
773
774 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
775 if (NULL == pInPtr)
776 {
777 *pLastArg = TRUE;
778 return NULL;
779 }
780 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
781
782 return pInPtr;
783}
784
785
786/**---------------------------------------------------------------------------
787
788 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
789
790 This function parses set batch scan command in below format:
791 WLS_BATCHING_SET <space> followed by below arguements
792 "SCANFREQ=XX" : Optional defaults to 30 sec
793 "MSCAN=XX" : Required number of scans to attempt to batch
794 "BESTN=XX" : Best Network (RSSI) defaults to 16
795 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
796 A. implies only 5 GHz , B. implies only 2.4GHz
797 "RTT=X" : optional defaults to 0
798 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
799 error
800
801 For example input commands:
802 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
803 translated into set batch scan with following parameters:
804 a) Frequence 60 seconds
805 b) Batch 10 scans together
806 c) Best RSSI to be 20
807 d) 5GHz band only
808 e) RTT is equal to 0
809
810 \param - pValue Pointer to input channel list
811 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
812
813 \return - 0 for success non-zero for failure
814
815 --------------------------------------------------------------------------*/
816static int
817hdd_parse_set_batchscan_command
818(
819 tANI_U8 *pValue,
820 tSirSetBatchScanReq *pHddSetBatchScanReq
821)
822{
823 tANI_U8 *inPtr = pValue;
824 tANI_U8 val = 0;
825 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800826 tANI_U32 nScanFreq;
827 tANI_U32 nMscan;
828 tANI_U32 nBestN;
829 tANI_U8 ucRfBand;
830 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800831 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530832
833 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800834 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
835 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
836 nRtt = 0;
837 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530838
839 /*go to space after WLS_BATCHING_SET command*/
840 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
841 /*no argument after the command*/
842 if (NULL == inPtr)
843 {
844 return -EINVAL;
845 }
846
847 /*no space after the command*/
848 else if (SPACE_ASCII_VALUE != *inPtr)
849 {
850 return -EINVAL;
851 }
852
853 /*removing empty spaces*/
854 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
855
856 /*no argument followed by spaces*/
857 if ('\0' == *inPtr)
858 {
859 return -EINVAL;
860 }
861
862 /*check and parse SCANFREQ*/
863 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
864 {
865 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800866 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800867
Rajeev Kumarc933d982013-11-18 20:04:20 -0800868 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800869 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800870 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800871 }
872
Rajeev79dbe4c2013-10-05 11:03:42 +0530873 if ( (NULL == inPtr) || (TRUE == lastArg))
874 {
875 return -EINVAL;
876 }
877 }
878
879 /*check and parse MSCAN*/
880 if ((strncmp(inPtr, "MSCAN", 5) == 0))
881 {
882 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800883 &nMscan, &lastArg);
884
885 if (0 == nMscan)
886 {
887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
888 "invalid MSCAN=%d", nMscan);
889 return -EINVAL;
890 }
891
Rajeev79dbe4c2013-10-05 11:03:42 +0530892 if (TRUE == lastArg)
893 {
894 goto done;
895 }
896 else if (NULL == inPtr)
897 {
898 return -EINVAL;
899 }
900 }
901 else
902 {
903 return -EINVAL;
904 }
905
906 /*check and parse BESTN*/
907 if ((strncmp(inPtr, "BESTN", 5) == 0))
908 {
909 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800910 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800911
Rajeev Kumarc933d982013-11-18 20:04:20 -0800912 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800913 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800914 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800915 }
916
Rajeev79dbe4c2013-10-05 11:03:42 +0530917 if (TRUE == lastArg)
918 {
919 goto done;
920 }
921 else if (NULL == inPtr)
922 {
923 return -EINVAL;
924 }
925 }
926
927 /*check and parse CHANNEL*/
928 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
929 {
930 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931
Rajeev79dbe4c2013-10-05 11:03:42 +0530932 if (('A' == val) || ('a' == val))
933 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530935 }
936 else if (('B' == val) || ('b' == val))
937 {
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800938 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530939 }
940 else
941 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800942 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
943 }
944
945 if (TRUE == lastArg)
946 {
947 goto done;
948 }
949 else if (NULL == inPtr)
950 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 return -EINVAL;
952 }
953 }
954
955 /*check and parse RTT*/
956 if ((strncmp(inPtr, "RTT", 3) == 0))
957 {
958 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800959 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530960 if (TRUE == lastArg)
961 {
962 goto done;
963 }
964 if (NULL == inPtr)
965 {
966 return -EINVAL;
967 }
968 }
969
970
971done:
972
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800973 pHddSetBatchScanReq->scanFrequency = nScanFreq;
974 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
975 pHddSetBatchScanReq->bestNetwork = nBestN;
976 pHddSetBatchScanReq->rfBand = ucRfBand;
977 pHddSetBatchScanReq->rtt = nRtt;
978
Rajeev79dbe4c2013-10-05 11:03:42 +0530979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
980 "Received WLS_BATCHING_SET with SCANFREQ=%d "
981 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
982 pHddSetBatchScanReq->scanFrequency,
983 pHddSetBatchScanReq->numberOfScansToBatch,
984 pHddSetBatchScanReq->bestNetwork,
985 pHddSetBatchScanReq->rfBand,
986 pHddSetBatchScanReq->rtt);
987
988 return 0;
989}/*End of hdd_parse_set_batchscan_command*/
990
991/**---------------------------------------------------------------------------
992
993 \brief hdd_set_batch_scan_req_callback () - This function is called after
994 receiving set batch scan response from FW and it saves set batch scan
995 response data FW to HDD context and sets the completion event on
996 which hdd_ioctl is waiting
997
998 \param - callbackContext Pointer to HDD adapter
999 \param - pRsp Pointer to set batch scan response data received from FW
1000
1001 \return - nothing
1002
1003 --------------------------------------------------------------------------*/
1004static void hdd_set_batch_scan_req_callback
1005(
1006 void *callbackContext,
1007 tSirSetBatchScanRsp *pRsp
1008)
1009{
1010 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1011 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1012
1013 /*sanity check*/
1014 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1015 {
1016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1017 "%s: Invalid pAdapter magic", __func__);
1018 VOS_ASSERT(0);
1019 return;
1020 }
1021 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1022
1023 /*save set batch scan response*/
1024 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1025
1026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1027 "Received set batch scan rsp from FW with nScansToBatch=%d",
1028 pHddSetBatchScanRsp->nScansToBatch);
1029
1030 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1031 complete(&pAdapter->hdd_set_batch_scan_req_var);
1032
1033 return;
1034}/*End of hdd_set_batch_scan_req_callback*/
1035
1036
1037/**---------------------------------------------------------------------------
1038
1039 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1040 info in hdd batch scan response queue
1041
1042 \param - pAdapter Pointer to hdd adapter
1043 \param - pAPMetaInfo Pointer to access point meta info
1044 \param - scanId scan ID of batch scan response
1045 \param - isLastAp tells whether AP is last AP in batch scan response or not
1046
1047 \return - nothing
1048
1049 --------------------------------------------------------------------------*/
1050static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1051 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1052{
1053 tHddBatchScanRsp *pHead;
1054 tHddBatchScanRsp *pNode;
1055 tHddBatchScanRsp *pPrev;
1056 tHddBatchScanRsp *pTemp;
1057 tANI_U8 ssidLen;
1058
1059 /*head of hdd batch scan response queue*/
1060 pHead = pAdapter->pBatchScanRsp;
1061
1062 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1063 if (NULL == pNode)
1064 {
1065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1066 "%s: Could not allocate memory", __func__);
1067 VOS_ASSERT(0);
1068 return;
1069 }
1070
1071 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1072 sizeof(pNode->ApInfo.bssid));
1073 ssidLen = strlen(pApMetaInfo->ssid);
1074 if (SIR_MAX_SSID_SIZE < ssidLen)
1075 {
1076 /*invalid scan result*/
1077 vos_mem_free(pNode);
1078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1079 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1080 return;
1081 }
1082 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1083 /*null terminate ssid*/
1084 pNode->ApInfo.ssid[ssidLen] = '\0';
1085 pNode->ApInfo.ch = pApMetaInfo->ch;
1086 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1087 pNode->ApInfo.age = pApMetaInfo->timestamp;
1088 pNode->ApInfo.batchId = scanId;
1089 pNode->ApInfo.isLastAp = isLastAp;
1090
1091 pNode->pNext = NULL;
1092 if (NULL == pHead)
1093 {
1094 pAdapter->pBatchScanRsp = pNode;
1095 }
1096 else
1097 {
1098 pTemp = pHead;
1099 while (NULL != pTemp)
1100 {
1101 pPrev = pTemp;
1102 pTemp = pTemp->pNext;
1103 }
1104 pPrev->pNext = pNode;
1105 }
1106
1107 return;
1108}/*End of hdd_populate_batch_scan_rsp_queue*/
1109
1110/**---------------------------------------------------------------------------
1111
1112 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1113 receiving batch scan response indication from FW. It saves get batch scan
1114 response data in HDD batch scan response queue. This callback sets the
1115 completion event on which hdd_ioctl is waiting only after getting complete
1116 batch scan response data from FW
1117
1118 \param - callbackContext Pointer to HDD adapter
1119 \param - pRsp Pointer to get batch scan response data received from FW
1120
1121 \return - nothing
1122
1123 --------------------------------------------------------------------------*/
1124static void hdd_batch_scan_result_ind_callback
1125(
1126 void *callbackContext,
1127 void *pRsp
1128)
1129{
1130 v_BOOL_t isLastAp;
1131 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001132 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301133 tANI_U32 numberScanList;
1134 tANI_U32 nextScanListOffset;
1135 tANI_U32 nextApMetaInfoOffset;
1136 hdd_adapter_t* pAdapter;
1137 tpSirBatchScanList pScanList;
1138 tpSirBatchScanNetworkInfo pApMetaInfo;
1139 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1140 tSirSetBatchScanReq *pReq;
1141
1142 pAdapter = (hdd_adapter_t *)callbackContext;
1143 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001144 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301145 {
1146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1147 "%s: Invalid pAdapter magic", __func__);
1148 VOS_ASSERT(0);
1149 return;
1150 }
1151
1152 /*initialize locals*/
1153 pReq = &pAdapter->hddSetBatchScanReq;
1154 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1155 isLastAp = FALSE;
1156 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001157 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301158 numberScanList = 0;
1159 nextScanListOffset = 0;
1160 nextApMetaInfoOffset = 0;
1161 pScanList = NULL;
1162 pApMetaInfo = NULL;
1163
1164 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1165 {
1166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1167 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1168 isLastAp = TRUE;
1169 goto done;
1170 }
1171
1172 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1174 "Batch scan rsp: numberScalList %d", numberScanList);
1175
1176 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1177 {
1178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1179 "%s: numberScanList %d", __func__, numberScanList);
1180 isLastAp = TRUE;
1181 goto done;
1182 }
1183
1184 while (numberScanList)
1185 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001186 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301187 nextScanListOffset);
1188 if (NULL == pScanList)
1189 {
1190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1191 "%s: pScanList is %p", __func__, pScanList);
1192 isLastAp = TRUE;
1193 goto done;
1194 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001195 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001197 "Batch scan rsp: numApMetaInfo %d scanId %d",
1198 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301199
1200 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1201 {
1202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1203 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1204 isLastAp = TRUE;
1205 goto done;
1206 }
1207
Rajeev Kumarce651e42013-10-21 18:57:15 -07001208 /*Initialize next AP meta info offset for next scan list*/
1209 nextApMetaInfoOffset = 0;
1210
Rajeev79dbe4c2013-10-05 11:03:42 +05301211 while (numApMetaInfo)
1212 {
1213 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1214 nextApMetaInfoOffset);
1215 if (NULL == pApMetaInfo)
1216 {
1217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1218 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1219 isLastAp = TRUE;
1220 goto done;
1221 }
1222 /*calculate AP age*/
1223 pApMetaInfo->timestamp =
1224 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1225
1226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001227 "%s: bssId "MAC_ADDRESS_STR
1228 " ch %d rssi %d timestamp %d", __func__,
1229 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1230 pApMetaInfo->ch, pApMetaInfo->rssi,
1231 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301232
1233 /*mark last AP in batch scan response*/
1234 if ((TRUE == pBatchScanRsp->isLastResult) &&
1235 (1 == numberScanList) && (1 == numApMetaInfo))
1236 {
1237 isLastAp = TRUE;
1238 }
1239
1240 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1241 /*store batch scan repsonse in hdd queue*/
1242 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1243 pScanList->scanId, isLastAp);
1244 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1245
1246 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1247 numApMetaInfo--;
1248 }
1249
Rajeev Kumarce651e42013-10-21 18:57:15 -07001250 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1251 + (sizeof(tSirBatchScanNetworkInfo)
1252 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301253 numberScanList--;
1254 }
1255
1256done:
1257
1258 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1259 requested from hdd_ioctl*/
1260 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1261 (TRUE == isLastAp))
1262 {
1263 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1264 complete(&pAdapter->hdd_get_batch_scan_req_var);
1265 }
1266
1267 return;
1268}/*End of hdd_batch_scan_result_ind_callback*/
1269
1270/**---------------------------------------------------------------------------
1271
1272 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1273 response as per batch scan FR request format by putting proper markers
1274
1275 \param - pDest pointer to destination buffer
1276 \param - cur_len current length
1277 \param - tot_len total remaining size which can be written to user space
1278 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1279 \param - pAdapter Pointer to HDD adapter
1280
1281 \return - ret no of characters written
1282
1283 --------------------------------------------------------------------------*/
1284static tANI_U32
1285hdd_format_batch_scan_rsp
1286(
1287 tANI_U8 *pDest,
1288 tANI_U32 cur_len,
1289 tANI_U32 tot_len,
1290 tHddBatchScanRsp *pApMetaInfo,
1291 hdd_adapter_t* pAdapter
1292)
1293{
1294 tANI_U32 ret = 0;
1295 tANI_U32 rem_len = 0;
1296 tANI_U8 temp_len = 0;
1297 tANI_U8 temp_total_len = 0;
1298 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1299 tANI_U8 *pTemp = temp;
1300
1301 /*Batch scan reponse needs to be returned to user space in
1302 following format:
1303 "scancount=X\n" where X is the number of scans in current batch
1304 batch
1305 "trunc\n" optional present if current scan truncated
1306 "bssid=XX:XX:XX:XX:XX:XX\n"
1307 "ssid=XXXX\n"
1308 "freq=X\n" frequency in Mhz
1309 "level=XX\n"
1310 "age=X\n" ms
1311 "dist=X\n" cm (-1 if not available)
1312 "errror=X\n" (-1if not available)
1313 "====\n" (end of ap marker)
1314 "####\n" (end of scan marker)
1315 "----\n" (end of results)*/
1316 /*send scan result in above format to user space based on
1317 available length*/
1318 /*The GET response may have more data than the driver can return in its
1319 buffer. In that case the buffer should be filled to the nearest complete
1320 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1321 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1322 The final buffer should end with "----\n"*/
1323
1324 /*sanity*/
1325 if (cur_len > tot_len)
1326 {
1327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1328 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1329 return 0;
1330 }
1331 else
1332 {
1333 rem_len = (tot_len - cur_len);
1334 }
1335
1336 /*end scan marker*/
1337 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1338 {
1339 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1340 pTemp += temp_len;
1341 temp_total_len += temp_len;
1342 }
1343
1344 /*bssid*/
1345 temp_len = snprintf(pTemp, sizeof(temp),
1346 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1347 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1348 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1349 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1350 pTemp += temp_len;
1351 temp_total_len += temp_len;
1352
1353 /*ssid*/
1354 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1355 pApMetaInfo->ApInfo.ssid);
1356 pTemp += temp_len;
1357 temp_total_len += temp_len;
1358
1359 /*freq*/
1360 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001361 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301362 pTemp += temp_len;
1363 temp_total_len += temp_len;
1364
1365 /*level*/
1366 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1367 pApMetaInfo->ApInfo.rssi);
1368 pTemp += temp_len;
1369 temp_total_len += temp_len;
1370
1371 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001372 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301373 pApMetaInfo->ApInfo.age);
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376
1377 /*dist*/
1378 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1379 pTemp += temp_len;
1380 temp_total_len += temp_len;
1381
1382 /*error*/
1383 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*end AP marker*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*last AP in batch scan response*/
1393 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1394 {
1395 /*end scan marker*/
1396 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1397 pTemp += temp_len;
1398 temp_total_len += temp_len;
1399
1400 /*end batch scan result marker*/
1401 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404 }
1405
1406 if (temp_total_len < rem_len)
1407 {
1408 ret = temp_total_len + 1;
1409 strlcpy(pDest, temp, ret);
1410 pAdapter->isTruncated = FALSE;
1411 }
1412 else
1413 {
1414 pAdapter->isTruncated = TRUE;
1415 if (rem_len >= strlen("%%%%"))
1416 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001417 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301418 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001419 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301420 {
1421 ret = 0;
1422 }
1423 }
1424
1425 return ret;
1426
1427}/*End of hdd_format_batch_scan_rsp*/
1428
1429/**---------------------------------------------------------------------------
1430
1431 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1432 buffer starting with head of hdd batch scan response queue
1433
1434 \param - pAdapter Pointer to HDD adapter
1435 \param - pDest Pointer to user data buffer
1436 \param - cur_len current offset in user buffer
1437 \param - rem_len remaining no of bytes in user buffer
1438
1439 \return - number of bytes written in user buffer
1440
1441 --------------------------------------------------------------------------*/
1442
1443tANI_U32 hdd_populate_user_batch_scan_rsp
1444(
1445 hdd_adapter_t* pAdapter,
1446 tANI_U8 *pDest,
1447 tANI_U32 cur_len,
1448 tANI_U32 rem_len
1449)
1450{
1451 tHddBatchScanRsp *pHead;
1452 tHddBatchScanRsp *pPrev;
1453 tANI_U32 len;
1454
Kiet Lam34947452014-01-21 23:23:40 -08001455 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301456 pAdapter->isTruncated = FALSE;
1457
1458 /*head of hdd batch scan response queue*/
1459 pHead = pAdapter->pBatchScanRsp;
1460 while (pHead)
1461 {
1462 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1463 pAdapter);
1464 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001465 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301466 cur_len += len;
1467 if(TRUE == pAdapter->isTruncated)
1468 {
1469 /*result is truncated return rest of scan rsp in next req*/
1470 cur_len = rem_len;
1471 break;
1472 }
1473 pPrev = pHead;
1474 pHead = pHead->pNext;
1475 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001476 if (TRUE == pPrev->ApInfo.isLastAp)
1477 {
1478 pAdapter->prev_batch_id = 0;
1479 }
1480 else
1481 {
1482 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1483 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301484 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001485 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 }
1487
1488 return cur_len;
1489}/*End of hdd_populate_user_batch_scan_rsp*/
1490
1491/**---------------------------------------------------------------------------
1492
1493 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1494 scan response data from HDD queue to user space
1495 It does following in detail:
1496 a) if HDD has enough data in its queue then it 1st copies data to user
1497 space and then send get batch scan indication message to FW. In this
1498 case it does not wait on any event and batch scan response data will
1499 be populated in HDD response queue in MC thread context after receiving
1500 indication from FW
1501 b) else send get batch scan indication message to FW and wait on an event
1502 which will be set once HDD receives complete batch scan response from
1503 FW and then this function returns batch scan response to user space
1504
1505 \param - pAdapter Pointer to HDD adapter
1506 \param - pPrivData Pointer to priv_data
1507
1508 \return - 0 for success -EFAULT for failure
1509
1510 --------------------------------------------------------------------------*/
1511
1512int hdd_return_batch_scan_rsp_to_user
1513(
1514 hdd_adapter_t* pAdapter,
1515 hdd_priv_data_t *pPrivData,
1516 tANI_U8 *command
1517)
1518{
1519 tANI_U8 *pDest;
1520 tANI_U32 count = 0;
1521 tANI_U32 len = 0;
1522 tANI_U32 cur_len = 0;
1523 tANI_U32 rem_len = 0;
1524 eHalStatus halStatus;
1525 unsigned long rc;
1526 tSirTriggerBatchScanResultInd *pReq;
1527
1528 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1529 pReq->param = 0;/*batch scan client*/
1530 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1531 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1532
1533 cur_len = pPrivData->used_len;
1534 if (pPrivData->total_len > pPrivData->used_len)
1535 {
1536 rem_len = pPrivData->total_len - pPrivData->used_len;
1537 }
1538 else
1539 {
1540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1541 "%s: Invalid user data buffer total_len %d used_len %d",
1542 __func__, pPrivData->total_len, pPrivData->used_len);
1543 return -EFAULT;
1544 }
1545
1546 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1547 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1548 cur_len, rem_len);
1549 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1550
1551 /*enough scan result available in cache to return to user space or
1552 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001553 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301554 {
1555 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1556 halStatus = sme_TriggerBatchScanResultInd(
1557 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1558 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1559 pAdapter);
1560 if ( eHAL_STATUS_SUCCESS == halStatus )
1561 {
1562 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1563 {
1564 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1565 rc = wait_for_completion_timeout(
1566 &pAdapter->hdd_get_batch_scan_req_var,
1567 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1568 if (0 == rc)
1569 {
1570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1571 "%s: Timeout waiting to fetch batch scan rsp from fw",
1572 __func__);
1573 return -EFAULT;
1574 }
1575 }
1576
1577 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001578 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301579 pDest += len;
1580 cur_len += len;
1581
1582 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1583 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1584 cur_len, rem_len);
1585 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1586
1587 count = 0;
1588 len = (len - pPrivData->used_len);
1589 pDest = (command + pPrivData->used_len);
1590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001591 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301592 while(count < len)
1593 {
1594 printk("%c", *(pDest + count));
1595 count++;
1596 }
1597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 "%s: copy %d data to user buffer", __func__, len);
1599 if (copy_to_user(pPrivData->buf, pDest, len))
1600 {
1601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1602 "%s: failed to copy data to user buffer", __func__);
1603 return -EFAULT;
1604 }
1605 }
1606 else
1607 {
1608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1609 "sme_GetBatchScanScan returned failure halStatus %d",
1610 halStatus);
1611 return -EINVAL;
1612 }
1613 }
1614 else
1615 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301616 count = 0;
1617 len = (len - pPrivData->used_len);
1618 pDest = (command + pPrivData->used_len);
1619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001620 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301621 while(count < len)
1622 {
1623 printk("%c", *(pDest + count));
1624 count++;
1625 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301628 if (copy_to_user(pPrivData->buf, pDest, len))
1629 {
1630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1631 "%s: failed to copy data to user buffer", __func__);
1632 return -EFAULT;
1633 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301634 }
1635
1636 return 0;
1637} /*End of hdd_return_batch_scan_rsp_to_user*/
1638
Rajeev Kumar8b373292014-01-08 20:36:55 -08001639
1640/**---------------------------------------------------------------------------
1641
1642 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1643 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1644 WLS_BATCHING VERSION
1645 WLS_BATCHING SET
1646 WLS_BATCHING GET
1647 WLS_BATCHING STOP
1648
1649 \param - pAdapter Pointer to HDD adapter
1650 \param - pPrivdata Pointer to priv_data
1651 \param - command Pointer to command
1652
1653 \return - 0 for success -EFAULT for failure
1654
1655 --------------------------------------------------------------------------*/
1656
1657int hdd_handle_batch_scan_ioctl
1658(
1659 hdd_adapter_t *pAdapter,
1660 hdd_priv_data_t *pPrivdata,
1661 tANI_U8 *command
1662)
1663{
1664 int ret = 0;
1665
1666 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1667 {
1668 char extra[32];
1669 tANI_U8 len = 0;
1670 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1671
1672 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1673 {
1674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1675 "%s: Batch scan feature is not supported by FW", __func__);
1676 ret = -EINVAL;
1677 goto exit;
1678 }
1679
1680 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1681 version);
1682 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1683 {
1684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to copy data to user buffer", __func__);
1686 ret = -EFAULT;
1687 goto exit;
1688 }
1689 ret = HDD_BATCH_SCAN_VERSION;
1690 }
1691 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1692 {
1693 int status;
1694 tANI_U8 *value = (command + 16);
1695 eHalStatus halStatus;
1696 unsigned long rc;
1697 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1698 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1699
1700 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1701 {
1702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1703 "%s: Batch scan feature is not supported by FW", __func__);
1704 ret = -EINVAL;
1705 goto exit;
1706 }
1707
1708 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1709 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1710 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1711 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1712 {
1713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1714 "Received WLS_BATCHING SET command in invalid mode %d "
1715 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
1716 pAdapter->device_mode);
1717 ret = -EINVAL;
1718 goto exit;
1719 }
1720
1721 status = hdd_parse_set_batchscan_command(value, pReq);
1722 if (status)
1723 {
1724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1725 "Invalid WLS_BATCHING SET command");
1726 ret = -EINVAL;
1727 goto exit;
1728 }
1729
1730
1731 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1732 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1733 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1734 pAdapter);
1735
1736 if ( eHAL_STATUS_SUCCESS == halStatus )
1737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1739 "sme_SetBatchScanReq returned success halStatus %d",
1740 halStatus);
1741 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1742 {
1743 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1744 rc = wait_for_completion_timeout(
1745 &pAdapter->hdd_set_batch_scan_req_var,
1746 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1747 if (0 == rc)
1748 {
1749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "%s: Timeout waiting for set batch scan to complete",
1751 __func__);
1752 ret = -EINVAL;
1753 goto exit;
1754 }
1755 }
1756 if ( !pRsp->nScansToBatch )
1757 {
1758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1759 "%s: Received set batch scan failure response from FW",
1760 __func__);
1761 ret = -EINVAL;
1762 goto exit;
1763 }
1764 /*As per the Batch Scan Framework API we should return the MIN of
1765 either MSCAN or the max # of scans firmware can cache*/
1766 ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
1767
1768 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1769
1770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1771 "%s: request MSCAN %d response MSCAN %d ret %d",
1772 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret);
1773 }
1774 else
1775 {
1776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1777 "sme_SetBatchScanReq returned failure halStatus %d",
1778 halStatus);
1779 ret = -EINVAL;
1780 goto exit;
1781 }
1782 }
1783 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1784 {
1785 eHalStatus halStatus;
1786 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1787 pInd->param = 0;
1788
1789 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1790 {
1791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "%s: Batch scan feature is not supported by FW", __func__);
1793 ret = -EINVAL;
1794 goto exit;
1795 }
1796
1797 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1798 {
1799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "Batch scan is not yet enabled batch scan state %d",
1801 pAdapter->batchScanState);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805
1806 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1807
1808 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1809 pAdapter->sessionId);
1810 if ( eHAL_STATUS_SUCCESS == halStatus )
1811 {
1812 ret = 0;
1813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1814 "sme_StopBatchScanInd returned success halStatus %d",
1815 halStatus);
1816 }
1817 else
1818 {
1819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "sme_StopBatchScanInd returned failure halStatus %d",
1821 halStatus);
1822 ret = -EINVAL;
1823 goto exit;
1824 }
1825 }
1826 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1827 {
1828 tANI_U32 remain_len;
1829
1830 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1831 {
1832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1833 "%s: Batch scan feature is not supported by FW", __func__);
1834 ret = -EINVAL;
1835 goto exit;
1836 }
1837
1838 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "Batch scan is not yet enabled could not return results"
1842 "Batch Scan state %d",
1843 pAdapter->batchScanState);
1844 ret = -EINVAL;
1845 goto exit;
1846 }
1847
1848 pPrivdata->used_len = 16;
1849 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1850 if (remain_len < pPrivdata->total_len)
1851 {
1852 /*Clear previous batch scan response data if any*/
1853 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1854 }
1855 else
1856 {
1857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1858 "Invalid total length from user space can't fetch batch"
1859 " scan response total_len %d used_len %d remain len %d",
1860 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1861 ret = -EINVAL;
1862 goto exit;
1863 }
1864 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1865 }
1866
1867exit:
1868
1869 return ret;
1870}
1871
1872
Rajeev79dbe4c2013-10-05 11:03:42 +05301873#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1876{
1877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1878 hdd_priv_data_t priv_data;
1879 tANI_U8 *command = NULL;
1880 int ret = 0;
1881
1882 if (NULL == pAdapter)
1883 {
1884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001885 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001886 ret = -ENODEV;
1887 goto exit;
1888 }
1889
Jeff Johnsone7245742012-09-05 17:12:55 -07001890 if ((!ifr) || (!ifr->ifr_data))
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 {
1892 ret = -EINVAL;
1893 goto exit;
1894 }
1895
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001896 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1897 {
1898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1899 "%s:LOGP in Progress. Ignore!!!", __func__);
1900 ret = -EBUSY;
1901 goto exit;
1902 }
1903
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(hdd_priv_data_t)))
1905 {
1906 ret = -EFAULT;
1907 goto exit;
1908 }
1909
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08001910 if (priv_data.total_len <= 0 ||
1911 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001912 {
1913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1914 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1915 priv_data.total_len);
1916 ret = -EINVAL;
1917 goto exit;
1918 }
1919
1920 /* Allocate +1 for '\0' */
1921 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 if (!command)
1923 {
1924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001925 "%s: failed to allocate memory\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 ret = -ENOMEM;
1927 goto exit;
1928 }
1929
1930 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1931 {
1932 ret = -EFAULT;
1933 goto exit;
1934 }
1935
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001936 /* Making sure the command is NUL-terminated */
1937 command[priv_data.total_len] = '\0';
1938
Jeff Johnson295189b2012-06-20 16:38:30 -07001939 if ((SIOCDEVPRIVATE + 1) == cmd)
1940 {
1941 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1942
1943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07001944 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07001945
1946 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
1947 {
1948 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
1949 sizeof(tSirMacAddr)))
1950 {
1951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001952 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 ret = -EFAULT;
1954 }
1955 }
Amar Singhal0974e402013-02-12 14:27:46 -08001956 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 {
Amar Singhal0974e402013-02-12 14:27:46 -08001958 tANI_U8 *ptr = command ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 int ret = 0 ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08001960
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001962
1963 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08001966 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08001968 ret = hdd_setBand_helper(dev, ptr);
1969 }
Kiet Lamf040f472013-11-20 21:15:23 +05301970 else if(strncmp(command, "SETWMMPS", 8) == 0)
1971 {
1972 tANI_U8 *ptr = command;
1973 ret = hdd_wmmps_helper(pAdapter, ptr);
1974 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001975 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
1976 {
1977 char *country_code;
1978
1979 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001980
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001981 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07001982 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001983#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05301984 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07001985#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001986 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
1987 (void *)(tSmeChangeCountryCallback)
1988 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05301989 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07001990 if (eHAL_STATUS_SUCCESS == ret)
1991 {
1992 ret = wait_for_completion_interruptible_timeout(
1993 &pAdapter->change_country_code,
1994 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
1995 if (0 >= ret)
1996 {
1997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out",
1998 __func__);
1999 }
2000 }
2001 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002002 {
2003 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002004 "%s: SME Change Country code fail ret=%d", __func__, ret);
2005 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002006 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002007
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002008 }
2009 /*
2010 command should be a string having format
2011 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2012 */
Amar Singhal0974e402013-02-12 14:27:46 -08002013 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002014 {
Amar Singhal0974e402013-02-12 14:27:46 -08002015 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002016
2017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002018 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002019
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002020 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002021 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002022 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2023 {
2024 int suspend = 0;
2025 tANI_U8 *ptr = (tANI_U8*)command + 15;
2026
2027 suspend = *ptr - '0';
2028 hdd_set_wlan_suspend_mode(suspend);
2029 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002030#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2031 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2032 {
2033 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002034 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002035 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2036 eHalStatus status = eHAL_STATUS_SUCCESS;
2037
2038 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2039 value = value + 15;
2040
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002041 /* Convert the value from ascii to integer */
2042 ret = kstrtos8(value, 10, &rssi);
2043 if (ret < 0)
2044 {
2045 /* If the input value is greater than max value of datatype, then also
2046 kstrtou8 fails */
2047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2048 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002049 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002050 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2051 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2052 ret = -EINVAL;
2053 goto exit;
2054 }
2055
Srinivas Girigowdade697412013-02-14 16:31:48 -08002056 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002057
Srinivas Girigowdade697412013-02-14 16:31:48 -08002058 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2059 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2060 {
2061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2062 "Neighbor lookup threshold value %d is out of range"
2063 " (Min: %d Max: %d)", lookUpThreshold,
2064 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2065 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2066 ret = -EINVAL;
2067 goto exit;
2068 }
2069
2070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2071 "%s: Received Command to Set Roam trigger"
2072 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2073
2074 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2075 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2076 if (eHAL_STATUS_SUCCESS != status)
2077 {
2078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2079 "%s: Failed to set roam trigger, try again", __func__);
2080 ret = -EPERM;
2081 goto exit;
2082 }
2083
2084 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2085 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2086 }
2087 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2088 {
2089 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2090 int rssi = (-1) * lookUpThreshold;
2091 char extra[32];
2092 tANI_U8 len = 0;
2093
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002094 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002095 if (copy_to_user(priv_data.buf, &extra, len + 1))
2096 {
2097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2098 "%s: failed to copy data to user buffer", __func__);
2099 ret = -EFAULT;
2100 goto exit;
2101 }
2102 }
2103 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2104 {
2105 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002106 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002107 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002108
Srinivas Girigowdade697412013-02-14 16:31:48 -08002109 /* input refresh period is in terms of seconds */
2110 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2111 value = value + 18;
2112 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002113 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002114 if (ret < 0)
2115 {
2116 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002117 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002119 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002120 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002121 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2122 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002123 ret = -EINVAL;
2124 goto exit;
2125 }
2126
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002127 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2128 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002129 {
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002131 "Roam scan period value %d is out of range"
2132 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002133 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2134 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002135 ret = -EINVAL;
2136 goto exit;
2137 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002138 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002139
2140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2141 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002142 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002143
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002144 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2145 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002146 }
2147 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2148 {
2149 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2150 char extra[32];
2151 tANI_U8 len = 0;
2152
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002153 len = scnprintf(extra, sizeof(extra), "%s %d",
2154 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002155 /* Returned value is in units of seconds */
2156 if (copy_to_user(priv_data.buf, &extra, len + 1))
2157 {
2158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2159 "%s: failed to copy data to user buffer", __func__);
2160 ret = -EFAULT;
2161 goto exit;
2162 }
2163 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002164 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2165 {
2166 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002167 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002168 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002169
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002170 /* input refresh period is in terms of seconds */
2171 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2172 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002173
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002174 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002175 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002176 if (ret < 0)
2177 {
2178 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002179 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002181 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002182 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002183 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2184 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2185 ret = -EINVAL;
2186 goto exit;
2187 }
2188
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002189 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2190 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2191 {
2192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2193 "Neighbor scan results refresh period value %d is out of range"
2194 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2195 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2196 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2197 ret = -EINVAL;
2198 goto exit;
2199 }
2200 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2201
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2203 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002204 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002205
2206 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2207 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2208 }
2209 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2210 {
2211 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2212 char extra[32];
2213 tANI_U8 len = 0;
2214
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002215 len = scnprintf(extra, sizeof(extra), "%s %d",
2216 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002217 /* Returned value is in units of seconds */
2218 if (copy_to_user(priv_data.buf, &extra, len + 1))
2219 {
2220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2221 "%s: failed to copy data to user buffer", __func__);
2222 ret = -EFAULT;
2223 goto exit;
2224 }
2225 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002226#ifdef FEATURE_WLAN_LFR
2227 /* SETROAMMODE */
2228 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2229 {
2230 tANI_U8 *value = command;
2231 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2232
2233 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2234 value = value + SIZE_OF_SETROAMMODE + 1;
2235
2236 /* Convert the value from ascii to integer */
2237 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2238 if (ret < 0)
2239 {
2240 /* If the input value is greater than max value of datatype, then also
2241 kstrtou8 fails */
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2243 "%s: kstrtou8 failed range [%d - %d]", __func__,
2244 CFG_LFR_FEATURE_ENABLED_MIN,
2245 CFG_LFR_FEATURE_ENABLED_MAX);
2246 ret = -EINVAL;
2247 goto exit;
2248 }
2249 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2250 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2251 {
2252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2253 "Roam Mode value %d is out of range"
2254 " (Min: %d Max: %d)", roamMode,
2255 CFG_LFR_FEATURE_ENABLED_MIN,
2256 CFG_LFR_FEATURE_ENABLED_MAX);
2257 ret = -EINVAL;
2258 goto exit;
2259 }
2260
2261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2262 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2263 /*
2264 * Note that
2265 * SETROAMMODE 0 is to enable LFR while
2266 * SETROAMMODE 1 is to disable LFR, but
2267 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2268 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2269 */
2270 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2271 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2272 else
2273 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2274
2275 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2276 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2277 }
2278 /* GETROAMMODE */
2279 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2280 {
2281 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2282 char extra[32];
2283 tANI_U8 len = 0;
2284
2285 /*
2286 * roamMode value shall be inverted because the sementics is different.
2287 */
2288 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2289 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2290 else
2291 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2292
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002293 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002294 if (copy_to_user(priv_data.buf, &extra, len + 1))
2295 {
2296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2297 "%s: failed to copy data to user buffer", __func__);
2298 ret = -EFAULT;
2299 goto exit;
2300 }
2301 }
2302#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002303#endif
2304#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2305 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2306 {
2307 tANI_U8 *value = command;
2308 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2309
2310 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2311 value = value + 13;
2312 /* Convert the value from ascii to integer */
2313 ret = kstrtou8(value, 10, &roamRssiDiff);
2314 if (ret < 0)
2315 {
2316 /* If the input value is greater than max value of datatype, then also
2317 kstrtou8 fails */
2318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2319 "%s: kstrtou8 failed range [%d - %d]", __func__,
2320 CFG_ROAM_RSSI_DIFF_MIN,
2321 CFG_ROAM_RSSI_DIFF_MAX);
2322 ret = -EINVAL;
2323 goto exit;
2324 }
2325
2326 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2327 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2328 {
2329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2330 "Roam rssi diff value %d is out of range"
2331 " (Min: %d Max: %d)", roamRssiDiff,
2332 CFG_ROAM_RSSI_DIFF_MIN,
2333 CFG_ROAM_RSSI_DIFF_MAX);
2334 ret = -EINVAL;
2335 goto exit;
2336 }
2337
2338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2339 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2340
2341 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2342 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2343 }
2344 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2345 {
2346 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2347 char extra[32];
2348 tANI_U8 len = 0;
2349
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002350 len = scnprintf(extra, sizeof(extra), "%s %d",
2351 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002352 if (copy_to_user(priv_data.buf, &extra, len + 1))
2353 {
2354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2355 "%s: failed to copy data to user buffer", __func__);
2356 ret = -EFAULT;
2357 goto exit;
2358 }
2359 }
2360#endif
2361#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
2362 else if (strncmp(command, "GETBAND", 7) == 0)
2363 {
2364 int band = -1;
2365 char extra[32];
2366 tANI_U8 len = 0;
2367 hdd_getBand_helper(pHddCtx, &band);
2368
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002369 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002370 if (copy_to_user(priv_data.buf, &extra, len + 1))
2371 {
2372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "%s: failed to copy data to user buffer", __func__);
2374 ret = -EFAULT;
2375 goto exit;
2376 }
2377 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002378 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2379 {
2380 tANI_U8 *value = command;
2381 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2382 tANI_U8 numChannels = 0;
2383 eHalStatus status = eHAL_STATUS_SUCCESS;
2384
2385 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2386 if (eHAL_STATUS_SUCCESS != status)
2387 {
2388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2389 "%s: Failed to parse channel list information", __func__);
2390 ret = -EINVAL;
2391 goto exit;
2392 }
2393
2394 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2395 {
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2397 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2398 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2399 ret = -EINVAL;
2400 goto exit;
2401 }
2402 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2403 numChannels);
2404 if (eHAL_STATUS_SUCCESS != status)
2405 {
2406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2407 "%s: Failed to update channel list information", __func__);
2408 ret = -EINVAL;
2409 goto exit;
2410 }
2411 }
2412 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2413 {
2414 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2415 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002416 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002417 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002418 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002419
2420 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2421 ChannelList, &numChannels ))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2424 "%s: failed to get roam scan channel list", __func__);
2425 ret = -EFAULT;
2426 goto exit;
2427 }
2428 /* output channel list is of the format
2429 [Number of roam scan channels][Channel1][Channel2]... */
2430 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002431 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002432 for (j = 0; (j < numChannels); j++)
2433 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002434 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2435 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002436 }
2437
2438 if (copy_to_user(priv_data.buf, &extra, len + 1))
2439 {
2440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2441 "%s: failed to copy data to user buffer", __func__);
2442 ret = -EFAULT;
2443 goto exit;
2444 }
2445 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002446 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2447 {
2448 tANI_BOOLEAN ccxMode = sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2449 char extra[32];
2450 tANI_U8 len = 0;
2451
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002452 /* Check if the features OKC/CCX/11R are supported simultaneously,
2453 then this operation is not permitted (return FAILURE) */
2454 if (ccxMode &&
2455 hdd_is_okc_mode_enabled(pHddCtx) &&
2456 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2457 {
2458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2459 "%s: OKC/CCX/11R are supported simultaneously"
2460 " hence this operation is not permitted!", __func__);
2461 ret = -EPERM;
2462 goto exit;
2463 }
2464
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002465 len = scnprintf(extra, sizeof(extra), "%s %d",
2466 "GETCCXMODE", ccxMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002467 if (copy_to_user(priv_data.buf, &extra, len + 1))
2468 {
2469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2470 "%s: failed to copy data to user buffer", __func__);
2471 ret = -EFAULT;
2472 goto exit;
2473 }
2474 }
2475 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2476 {
2477 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2478 char extra[32];
2479 tANI_U8 len = 0;
2480
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002481 /* Check if the features OKC/CCX/11R are supported simultaneously,
2482 then this operation is not permitted (return FAILURE) */
2483 if (okcMode &&
2484 sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
2485 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2486 {
2487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2488 "%s: OKC/CCX/11R are supported simultaneously"
2489 " hence this operation is not permitted!", __func__);
2490 ret = -EPERM;
2491 goto exit;
2492 }
2493
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002494 len = scnprintf(extra, sizeof(extra), "%s %d",
2495 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002496 if (copy_to_user(priv_data.buf, &extra, len + 1))
2497 {
2498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2499 "%s: failed to copy data to user buffer", __func__);
2500 ret = -EFAULT;
2501 goto exit;
2502 }
2503 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002504 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002505 {
2506 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2507 char extra[32];
2508 tANI_U8 len = 0;
2509
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002510 len = scnprintf(extra, sizeof(extra), "%s %d",
2511 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 if (copy_to_user(priv_data.buf, &extra, len + 1))
2513 {
2514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2515 "%s: failed to copy data to user buffer", __func__);
2516 ret = -EFAULT;
2517 goto exit;
2518 }
2519 }
2520 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2521 {
2522 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2523 char extra[32];
2524 tANI_U8 len = 0;
2525
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002526 len = scnprintf(extra, sizeof(extra), "%s %d",
2527 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002528 if (copy_to_user(priv_data.buf, &extra, len + 1))
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2531 "%s: failed to copy data to user buffer", __func__);
2532 ret = -EFAULT;
2533 goto exit;
2534 }
2535 }
2536 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2537 {
2538 tANI_U8 *value = command;
2539 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2540
2541 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2542 value = value + 26;
2543 /* Convert the value from ascii to integer */
2544 ret = kstrtou8(value, 10, &minTime);
2545 if (ret < 0)
2546 {
2547 /* If the input value is greater than max value of datatype, then also
2548 kstrtou8 fails */
2549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2550 "%s: kstrtou8 failed range [%d - %d]", __func__,
2551 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2552 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2553 ret = -EINVAL;
2554 goto exit;
2555 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002556 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2557 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2558 {
2559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2560 "scan min channel time value %d is out of range"
2561 " (Min: %d Max: %d)", minTime,
2562 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2563 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2564 ret = -EINVAL;
2565 goto exit;
2566 }
2567
2568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2569 "%s: Received Command to change channel min time = %d", __func__, minTime);
2570
2571 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2572 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2573 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002574 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2575 {
2576 tANI_U8 *value = command;
2577 tANI_U8 channel = 0;
2578 tANI_U8 dwellTime = 0;
2579 tANI_U8 bufLen = 0;
2580 tANI_U8 *buf = NULL;
2581 tSirMacAddr targetApBssid;
2582 eHalStatus status = eHAL_STATUS_SUCCESS;
2583 struct ieee80211_channel chan;
2584 tANI_U8 finalLen = 0;
2585 tANI_U8 *finalBuf = NULL;
2586 tANI_U8 temp = 0;
2587 u64 cookie;
2588 hdd_station_ctx_t *pHddStaCtx = NULL;
2589 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2590
2591 /* if not associated, no need to send action frame */
2592 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2593 {
2594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2595 ret = -EINVAL;
2596 goto exit;
2597 }
2598
2599 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2600 &dwellTime, &buf, &bufLen);
2601 if (eHAL_STATUS_SUCCESS != status)
2602 {
2603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2604 "%s: Failed to parse send action frame data", __func__);
2605 ret = -EINVAL;
2606 goto exit;
2607 }
2608
2609 /* if the target bssid is different from currently associated AP,
2610 then no need to send action frame */
2611 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2612 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2613 {
2614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2615 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002616 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002617 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002618 goto exit;
2619 }
2620
2621 /* if the channel number is different from operating channel then
2622 no need to send action frame */
2623 if (channel != pHddStaCtx->conn_info.operationChannel)
2624 {
2625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2626 "%s: channel(%d) is different from operating channel(%d)",
2627 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2628 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002629 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002630 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002631 goto exit;
2632 }
2633 chan.center_freq = sme_ChnToFreq(channel);
2634
2635 finalLen = bufLen + 24;
2636 finalBuf = vos_mem_malloc(finalLen);
2637 if (NULL == finalBuf)
2638 {
2639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2640 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002641 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002642 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002643 goto exit;
2644 }
2645 vos_mem_zero(finalBuf, finalLen);
2646
2647 /* Fill subtype */
2648 temp = SIR_MAC_MGMT_ACTION << 4;
2649 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2650
2651 /* Fill type */
2652 temp = SIR_MAC_MGMT_FRAME;
2653 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2654
2655 /* Fill destination address (bssid of the AP) */
2656 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2657
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002658 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002659 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2660
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002661 /* Fill BSSID (AP mac address) */
2662 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002663
2664 /* Fill received buffer from 24th address */
2665 vos_mem_copy(finalBuf + 24, buf, bufLen);
2666
Jeff Johnson11c33152013-04-16 17:52:40 -07002667 /* done with the parsed buffer */
2668 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002669 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002670
Yue Maf49ba872013-08-19 12:04:25 -07002671 wlan_hdd_action( NULL,
2672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2673 &(pAdapter->wdev),
2674#else
2675 dev,
2676#endif
2677 &chan, 0,
2678#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2679 NL80211_CHAN_HT20, 1,
2680#endif
2681 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002682 1, &cookie );
2683 vos_mem_free(finalBuf);
2684 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002685 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2686 {
2687 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2688 char extra[32];
2689 tANI_U8 len = 0;
2690
2691 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002692 len = scnprintf(extra, sizeof(extra), "%s %d",
2693 "GETROAMSCANCHANNELMINTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002694 if (copy_to_user(priv_data.buf, &extra, len + 1))
2695 {
2696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2697 "%s: failed to copy data to user buffer", __func__);
2698 ret = -EFAULT;
2699 goto exit;
2700 }
2701 }
2702 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2703 {
2704 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002705 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002706
2707 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2708 value = value + 19;
2709 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002710 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002711 if (ret < 0)
2712 {
2713 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002714 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002716 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002717 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2718 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2719 ret = -EINVAL;
2720 goto exit;
2721 }
2722
2723 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2724 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2725 {
2726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2727 "lfr mode value %d is out of range"
2728 " (Min: %d Max: %d)", maxTime,
2729 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2730 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2731 ret = -EINVAL;
2732 goto exit;
2733 }
2734
2735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2736 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2737
2738 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2739 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2740 }
2741 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2742 {
2743 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2744 char extra[32];
2745 tANI_U8 len = 0;
2746
2747 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002748 len = scnprintf(extra, sizeof(extra), "%s %d",
2749 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002750 if (copy_to_user(priv_data.buf, &extra, len + 1))
2751 {
2752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2753 "%s: failed to copy data to user buffer", __func__);
2754 ret = -EFAULT;
2755 goto exit;
2756 }
2757 }
2758 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2759 {
2760 tANI_U8 *value = command;
2761 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2762
2763 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2764 value = value + 16;
2765 /* Convert the value from ascii to integer */
2766 ret = kstrtou16(value, 10, &val);
2767 if (ret < 0)
2768 {
2769 /* If the input value is greater than max value of datatype, then also
2770 kstrtou16 fails */
2771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2772 "%s: kstrtou16 failed range [%d - %d]", __func__,
2773 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2774 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2775 ret = -EINVAL;
2776 goto exit;
2777 }
2778
2779 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2780 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2781 {
2782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2783 "scan home time value %d is out of range"
2784 " (Min: %d Max: %d)", val,
2785 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2786 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2787 ret = -EINVAL;
2788 goto exit;
2789 }
2790
2791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2792 "%s: Received Command to change scan home time = %d", __func__, val);
2793
2794 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2795 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2796 }
2797 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2798 {
2799 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2800 char extra[32];
2801 tANI_U8 len = 0;
2802
2803 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002804 len = scnprintf(extra, sizeof(extra), "%s %d",
2805 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002806 if (copy_to_user(priv_data.buf, &extra, len + 1))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2809 "%s: failed to copy data to user buffer", __func__);
2810 ret = -EFAULT;
2811 goto exit;
2812 }
2813 }
2814 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2815 {
2816 tANI_U8 *value = command;
2817 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2818
2819 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2820 value = value + 17;
2821 /* Convert the value from ascii to integer */
2822 ret = kstrtou8(value, 10, &val);
2823 if (ret < 0)
2824 {
2825 /* If the input value is greater than max value of datatype, then also
2826 kstrtou8 fails */
2827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: kstrtou8 failed range [%d - %d]", __func__,
2829 CFG_ROAM_INTRA_BAND_MIN,
2830 CFG_ROAM_INTRA_BAND_MAX);
2831 ret = -EINVAL;
2832 goto exit;
2833 }
2834
2835 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2836 (val > CFG_ROAM_INTRA_BAND_MAX))
2837 {
2838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2839 "intra band mode value %d is out of range"
2840 " (Min: %d Max: %d)", val,
2841 CFG_ROAM_INTRA_BAND_MIN,
2842 CFG_ROAM_INTRA_BAND_MAX);
2843 ret = -EINVAL;
2844 goto exit;
2845 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2847 "%s: Received Command to change intra band = %d", __func__, val);
2848
2849 pHddCtx->cfg_ini->nRoamIntraBand = val;
2850 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2851 }
2852 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2853 {
2854 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2855 char extra[32];
2856 tANI_U8 len = 0;
2857
2858 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002859 len = scnprintf(extra, sizeof(extra), "%s %d",
2860 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002861 if (copy_to_user(priv_data.buf, &extra, len + 1))
2862 {
2863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2864 "%s: failed to copy data to user buffer", __func__);
2865 ret = -EFAULT;
2866 goto exit;
2867 }
2868 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002869 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2870 {
2871 tANI_U8 *value = command;
2872 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2873
2874 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2875 value = value + 15;
2876 /* Convert the value from ascii to integer */
2877 ret = kstrtou8(value, 10, &nProbes);
2878 if (ret < 0)
2879 {
2880 /* If the input value is greater than max value of datatype, then also
2881 kstrtou8 fails */
2882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2883 "%s: kstrtou8 failed range [%d - %d]", __func__,
2884 CFG_ROAM_SCAN_N_PROBES_MIN,
2885 CFG_ROAM_SCAN_N_PROBES_MAX);
2886 ret = -EINVAL;
2887 goto exit;
2888 }
2889
2890 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2891 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2892 {
2893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2894 "NProbes value %d is out of range"
2895 " (Min: %d Max: %d)", nProbes,
2896 CFG_ROAM_SCAN_N_PROBES_MIN,
2897 CFG_ROAM_SCAN_N_PROBES_MAX);
2898 ret = -EINVAL;
2899 goto exit;
2900 }
2901
2902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2903 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
2904
2905 pHddCtx->cfg_ini->nProbes = nProbes;
2906 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
2907 }
2908 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
2909 {
2910 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
2911 char extra[32];
2912 tANI_U8 len = 0;
2913
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002914 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002915 if (copy_to_user(priv_data.buf, &extra, len + 1))
2916 {
2917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2918 "%s: failed to copy data to user buffer", __func__);
2919 ret = -EFAULT;
2920 goto exit;
2921 }
2922 }
2923 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
2924 {
2925 tANI_U8 *value = command;
2926 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
2927
2928 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
2929 /* input value is in units of msec */
2930 value = value + 20;
2931 /* Convert the value from ascii to integer */
2932 ret = kstrtou16(value, 10, &homeAwayTime);
2933 if (ret < 0)
2934 {
2935 /* If the input value is greater than max value of datatype, then also
2936 kstrtou8 fails */
2937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2938 "%s: kstrtou8 failed range [%d - %d]", __func__,
2939 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2940 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2941 ret = -EINVAL;
2942 goto exit;
2943 }
2944
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002945 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
2946 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
2947 {
2948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2949 "homeAwayTime value %d is out of range"
2950 " (Min: %d Max: %d)", homeAwayTime,
2951 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
2952 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
2953 ret = -EINVAL;
2954 goto exit;
2955 }
2956
2957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07002959 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
2960 {
2961 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
2962 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
2963 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002964 }
2965 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
2966 {
2967 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
2968 char extra[32];
2969 tANI_U8 len = 0;
2970
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002971 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002972 if (copy_to_user(priv_data.buf, &extra, len + 1))
2973 {
2974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2975 "%s: failed to copy data to user buffer", __func__);
2976 ret = -EFAULT;
2977 goto exit;
2978 }
2979 }
2980 else if (strncmp(command, "REASSOC", 7) == 0)
2981 {
2982 tANI_U8 *value = command;
2983 tANI_U8 channel = 0;
2984 tSirMacAddr targetApBssid;
2985 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07002986#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
2987 tCsrHandoffRequest handoffInfo;
2988#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002989 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002990 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2991
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002992 /* if not associated, no need to proceed with reassoc */
2993 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2994 {
2995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2996 ret = -EINVAL;
2997 goto exit;
2998 }
2999
3000 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3001 if (eHAL_STATUS_SUCCESS != status)
3002 {
3003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3004 "%s: Failed to parse reassoc command data", __func__);
3005 ret = -EINVAL;
3006 goto exit;
3007 }
3008
3009 /* if the target bssid is same as currently associated AP,
3010 then no need to proceed with reassoc */
3011 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3012 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3013 {
3014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3015 ret = -EINVAL;
3016 goto exit;
3017 }
3018
3019 /* Check channel number is a valid channel number */
3020 if(VOS_STATUS_SUCCESS !=
3021 wlan_hdd_validate_operation_channel(pAdapter, channel))
3022 {
3023 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003024 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003025 return -EINVAL;
3026 }
3027
3028 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003029#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3030 handoffInfo.channel = channel;
3031 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3032 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3033#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003034 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003035 else if (strncmp(command, "SETWESMODE", 10) == 0)
3036 {
3037 tANI_U8 *value = command;
3038 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3039
3040 /* Move pointer to ahead of SETWESMODE<delimiter> */
3041 value = value + 11;
3042 /* Convert the value from ascii to integer */
3043 ret = kstrtou8(value, 10, &wesMode);
3044 if (ret < 0)
3045 {
3046 /* If the input value is greater than max value of datatype, then also
3047 kstrtou8 fails */
3048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s: kstrtou8 failed range [%d - %d]", __func__,
3050 CFG_ENABLE_WES_MODE_NAME_MIN,
3051 CFG_ENABLE_WES_MODE_NAME_MAX);
3052 ret = -EINVAL;
3053 goto exit;
3054 }
3055
3056 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3057 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3058 {
3059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3060 "WES Mode value %d is out of range"
3061 " (Min: %d Max: %d)", wesMode,
3062 CFG_ENABLE_WES_MODE_NAME_MIN,
3063 CFG_ENABLE_WES_MODE_NAME_MAX);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3068 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3069
3070 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3071 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3072 }
3073 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3074 {
3075 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3076 char extra[32];
3077 tANI_U8 len = 0;
3078
Arif Hussain826d9412013-11-12 16:44:54 -08003079 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003080 if (copy_to_user(priv_data.buf, &extra, len + 1))
3081 {
3082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3083 "%s: failed to copy data to user buffer", __func__);
3084 ret = -EFAULT;
3085 goto exit;
3086 }
3087 }
3088#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_CCX || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003089#ifdef FEATURE_WLAN_LFR
3090 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3091 {
3092 tANI_U8 *value = command;
3093 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3094
3095 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3096 value = value + 12;
3097 /* Convert the value from ascii to integer */
3098 ret = kstrtou8(value, 10, &lfrMode);
3099 if (ret < 0)
3100 {
3101 /* If the input value is greater than max value of datatype, then also
3102 kstrtou8 fails */
3103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3104 "%s: kstrtou8 failed range [%d - %d]", __func__,
3105 CFG_LFR_FEATURE_ENABLED_MIN,
3106 CFG_LFR_FEATURE_ENABLED_MAX);
3107 ret = -EINVAL;
3108 goto exit;
3109 }
3110
3111 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3112 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3113 {
3114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3115 "lfr mode value %d is out of range"
3116 " (Min: %d Max: %d)", lfrMode,
3117 CFG_LFR_FEATURE_ENABLED_MIN,
3118 CFG_LFR_FEATURE_ENABLED_MAX);
3119 ret = -EINVAL;
3120 goto exit;
3121 }
3122
3123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3124 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3125
3126 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3127 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3128 }
3129#endif
3130#ifdef WLAN_FEATURE_VOWIFI_11R
3131 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3132 {
3133 tANI_U8 *value = command;
3134 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3135
3136 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3137 value = value + 18;
3138 /* Convert the value from ascii to integer */
3139 ret = kstrtou8(value, 10, &ft);
3140 if (ret < 0)
3141 {
3142 /* If the input value is greater than max value of datatype, then also
3143 kstrtou8 fails */
3144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3145 "%s: kstrtou8 failed range [%d - %d]", __func__,
3146 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3147 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3148 ret = -EINVAL;
3149 goto exit;
3150 }
3151
3152 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3153 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3154 {
3155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3156 "ft mode value %d is out of range"
3157 " (Min: %d Max: %d)", ft,
3158 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3159 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3160 ret = -EINVAL;
3161 goto exit;
3162 }
3163
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3165 "%s: Received Command to change ft mode = %d", __func__, ft);
3166
3167 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3168 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3169 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303170
3171 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3172 {
3173 tANI_U8 *value = command;
3174 tSirMacAddr targetApBssid;
3175 tANI_U8 trigger = 0;
3176 eHalStatus status = eHAL_STATUS_SUCCESS;
3177 hdd_station_ctx_t *pHddStaCtx = NULL;
3178 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3179
3180 /* if not associated, no need to proceed with reassoc */
3181 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3182 {
3183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3184 ret = -EINVAL;
3185 goto exit;
3186 }
3187
3188 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3189 if (eHAL_STATUS_SUCCESS != status)
3190 {
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3192 "%s: Failed to parse reassoc command data", __func__);
3193 ret = -EINVAL;
3194 goto exit;
3195 }
3196
3197 /* if the target bssid is same as currently associated AP,
3198 then no need to proceed with reassoc */
3199 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3200 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3201 {
3202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3203 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3204 __func__);
3205 ret = -EINVAL;
3206 goto exit;
3207 }
3208
3209 /* Proceed with scan/roam */
3210 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3211 &targetApBssid[0],
3212 (tSmeFastRoamTrigger)(trigger));
3213 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003214#endif
3215#ifdef FEATURE_WLAN_CCX
3216 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3217 {
3218 tANI_U8 *value = command;
3219 tANI_U8 ccxMode = CFG_CCX_FEATURE_ENABLED_DEFAULT;
3220
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003221 /* Check if the features OKC/CCX/11R are supported simultaneously,
3222 then this operation is not permitted (return FAILURE) */
3223 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3224 hdd_is_okc_mode_enabled(pHddCtx) &&
3225 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3226 {
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3228 "%s: OKC/CCX/11R are supported simultaneously"
3229 " hence this operation is not permitted!", __func__);
3230 ret = -EPERM;
3231 goto exit;
3232 }
3233
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003234 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3235 value = value + 11;
3236 /* Convert the value from ascii to integer */
3237 ret = kstrtou8(value, 10, &ccxMode);
3238 if (ret < 0)
3239 {
3240 /* If the input value is greater than max value of datatype, then also
3241 kstrtou8 fails */
3242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3243 "%s: kstrtou8 failed range [%d - %d]", __func__,
3244 CFG_CCX_FEATURE_ENABLED_MIN,
3245 CFG_CCX_FEATURE_ENABLED_MAX);
3246 ret = -EINVAL;
3247 goto exit;
3248 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003249 if ((ccxMode < CFG_CCX_FEATURE_ENABLED_MIN) ||
3250 (ccxMode > CFG_CCX_FEATURE_ENABLED_MAX))
3251 {
3252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3253 "Ccx mode value %d is out of range"
3254 " (Min: %d Max: %d)", ccxMode,
3255 CFG_CCX_FEATURE_ENABLED_MIN,
3256 CFG_CCX_FEATURE_ENABLED_MAX);
3257 ret = -EINVAL;
3258 goto exit;
3259 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3261 "%s: Received Command to change ccx mode = %d", __func__, ccxMode);
3262
3263 pHddCtx->cfg_ini->isCcxIniFeatureEnabled = ccxMode;
3264 sme_UpdateIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal), ccxMode);
3265 }
3266#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003267 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3268 {
3269 tANI_U8 *value = command;
3270 tANI_BOOLEAN roamScanControl = 0;
3271
3272 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3273 value = value + 19;
3274 /* Convert the value from ascii to integer */
3275 ret = kstrtou8(value, 10, &roamScanControl);
3276 if (ret < 0)
3277 {
3278 /* If the input value is greater than max value of datatype, then also
3279 kstrtou8 fails */
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: kstrtou8 failed ", __func__);
3282 ret = -EINVAL;
3283 goto exit;
3284 }
3285
3286 if (0 != roamScanControl)
3287 {
3288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3289 "roam scan control invalid value = %d",
3290 roamScanControl);
3291 ret = -EINVAL;
3292 goto exit;
3293 }
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3295 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3296
3297 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3298 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003299#ifdef FEATURE_WLAN_OKC
3300 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3301 {
3302 tANI_U8 *value = command;
3303 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3304
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003305 /* Check if the features OKC/CCX/11R are supported simultaneously,
3306 then this operation is not permitted (return FAILURE) */
3307 if (sme_getIsCcxFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
3308 hdd_is_okc_mode_enabled(pHddCtx) &&
3309 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3310 {
3311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
3312 "%s: OKC/CCX/11R are supported simultaneously"
3313 " hence this operation is not permitted!", __func__);
3314 ret = -EPERM;
3315 goto exit;
3316 }
3317
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003318 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3319 value = value + 11;
3320 /* Convert the value from ascii to integer */
3321 ret = kstrtou8(value, 10, &okcMode);
3322 if (ret < 0)
3323 {
3324 /* If the input value is greater than max value of datatype, then also
3325 kstrtou8 fails */
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s: kstrtou8 failed range [%d - %d]", __func__,
3328 CFG_OKC_FEATURE_ENABLED_MIN,
3329 CFG_OKC_FEATURE_ENABLED_MAX);
3330 ret = -EINVAL;
3331 goto exit;
3332 }
3333
3334 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3335 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3336 {
3337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3338 "Okc mode value %d is out of range"
3339 " (Min: %d Max: %d)", okcMode,
3340 CFG_OKC_FEATURE_ENABLED_MIN,
3341 CFG_OKC_FEATURE_ENABLED_MAX);
3342 ret = -EINVAL;
3343 goto exit;
3344 }
3345
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3347 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3348
3349 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3350 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003351#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003352 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3353 {
3354 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3355 char extra[32];
3356 tANI_U8 len = 0;
3357
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003358 len = scnprintf(extra, sizeof(extra), "%s %d",
3359 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003360 if (copy_to_user(priv_data.buf, &extra, len + 1))
3361 {
3362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3363 "%s: failed to copy data to user buffer", __func__);
3364 ret = -EFAULT;
3365 goto exit;
3366 }
3367 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303368#ifdef WLAN_FEATURE_PACKET_FILTERING
3369 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3370 {
3371 tANI_U8 filterType = 0;
3372 tANI_U8 *value = command;
3373
3374 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3375 value = value + 22;
3376
3377 /* Convert the value from ascii to integer */
3378 ret = kstrtou8(value, 10, &filterType);
3379 if (ret < 0)
3380 {
3381 /* If the input value is greater than max value of datatype,
3382 * then also kstrtou8 fails
3383 */
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: kstrtou8 failed range ", __func__);
3386 ret = -EINVAL;
3387 goto exit;
3388 }
3389
3390 if (filterType != 0 && filterType != 1)
3391 {
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3393 "%s: Accepted Values are 0 and 1 ", __func__);
3394 ret = -EINVAL;
3395 goto exit;
3396 }
3397 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3398 pAdapter->sessionId);
3399 }
3400#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303401 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3402 {
3403 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303404 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303405 if ('1' == *dhcpPhase)
3406 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3408 FL("BTCOEXMODE %d"), *dhcpPhase);
3409
3410 pHddCtx->btCoexModeSet = TRUE;
3411
3412 /* Firmware failing to process DHCP START/STOP indications.
3413 * So, for now commentig below code, once issue is resolved,
3414 * follwing will be uncommented.
3415 */
3416 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303417 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3418 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303419 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303420 }
3421 else if ('2' == *dhcpPhase)
3422 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3424 FL("BTCOEXMODE %d"), *dhcpPhase);
3425
3426 pHddCtx->btCoexModeSet = FALSE;
3427
3428 /* Firmware failing to process DHCP START/STOP indications.
3429 * So, for now commentig below code, once issue is resolved,
3430 * follwing will be uncommented.
3431 */
3432 #if 0
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303433 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3434 pAdapter->macAddressCurrent.bytes);
c_hpothu9b781ba2013-12-30 20:57:45 +05303435 #endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303436 }
3437 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003438 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3439 {
3440 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
3441 }
3442 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3443 {
3444 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
3445 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303446 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3447 {
3448 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3449 char extra[32];
3450 tANI_U8 len = 0;
3451
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003452 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303453 (int)pCfg->nActiveMaxChnTime);
3454 if (copy_to_user(priv_data.buf, &extra, len + 1))
3455 {
3456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3457 "%s: failed to copy data to user buffer", __func__);
3458 ret = -EFAULT;
3459 goto exit;
3460 }
3461 ret = len;
3462 }
3463 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3464 {
3465 tANI_U8 *value = command;
3466 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3467 int val = 0, temp;
3468
3469 value = value + 13;
3470 temp = kstrtou32(value, 10, &val);
3471 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3472 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3473 {
3474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3475 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3476 ret = -EFAULT;
3477 goto exit;
3478 }
3479 pCfg->nActiveMaxChnTime = val;
3480 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003481 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3482 {
3483 tANI_U8 filterType = 0;
3484 tANI_U8 *value;
3485 value = command + 9;
3486
3487 /* Convert the value from ascii to integer */
3488 ret = kstrtou8(value, 10, &filterType);
3489 if (ret < 0)
3490 {
3491 /* If the input value is greater than max value of datatype,
3492 * then also kstrtou8 fails
3493 */
3494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3495 "%s: kstrtou8 failed range ", __func__);
3496 ret = -EINVAL;
3497 goto exit;
3498 }
3499 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3500 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3501 {
3502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3503 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3504 " 2-Sink ", __func__);
3505 ret = -EINVAL;
3506 goto exit;
3507 }
3508 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3509 pHddCtx->drvr_miracast = filterType;
3510 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3511 }
Leo Chang614d2072013-08-22 14:59:44 -07003512 else if (strncmp(command, "SETMCRATE", 9) == 0)
3513 {
Leo Chang614d2072013-08-22 14:59:44 -07003514 tANI_U8 *value = command;
3515 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003516 tSirRateUpdateInd *rateUpdate;
3517 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003518
3519 /* Only valid for SAP mode */
3520 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3521 {
3522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3523 "%s: SAP mode is not running", __func__);
3524 ret = -EFAULT;
3525 goto exit;
3526 }
3527
3528 /* Move pointer to ahead of SETMCRATE<delimiter> */
3529 /* input value is in units of hundred kbps */
3530 value = value + 10;
3531 /* Convert the value from ascii to integer, decimal base */
3532 ret = kstrtouint(value, 10, &targetRate);
3533
Leo Chang1f98cbd2013-10-17 15:03:52 -07003534 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3535 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003536 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003537 hddLog(VOS_TRACE_LEVEL_ERROR,
3538 "%s: SETMCRATE indication alloc fail", __func__);
3539 ret = -EFAULT;
3540 goto exit;
3541 }
3542 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3543
3544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3545 "MC Target rate %d", targetRate);
3546 /* Ignore unicast */
3547 rateUpdate->ucastDataRate = -1;
3548 rateUpdate->mcastDataRate24GHz = targetRate;
3549 rateUpdate->mcastDataRate5GHz = targetRate;
3550 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3551 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3552 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3553 if (eHAL_STATUS_SUCCESS != status)
3554 {
3555 hddLog(VOS_TRACE_LEVEL_ERROR,
3556 "%s: SET_MC_RATE failed", __func__);
3557 vos_mem_free(rateUpdate);
3558 ret = -EFAULT;
3559 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003560 }
3561 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303562#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003563 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303564 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003565 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303566 }
3567#endif
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003568#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
3569 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3570 {
3571 tANI_U8 *value = command;
3572 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3573 tANI_U8 numChannels = 0;
3574 eHalStatus status = eHAL_STATUS_SUCCESS;
3575
3576 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3577 if (eHAL_STATUS_SUCCESS != status)
3578 {
3579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3580 "%s: Failed to parse channel list information", __func__);
3581 ret = -EINVAL;
3582 goto exit;
3583 }
3584
3585 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3586 {
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3588 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3589 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3590 ret = -EINVAL;
3591 goto exit;
3592 }
3593 status = sme_SetCcxRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
3594 ChannelList,
3595 numChannels);
3596 if (eHAL_STATUS_SUCCESS != status)
3597 {
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3599 "%s: Failed to update channel list information", __func__);
3600 ret = -EINVAL;
3601 goto exit;
3602 }
3603 }
3604 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3605 {
3606 tANI_U8 *value = command;
3607 char extra[128] = {0};
3608 int len = 0;
3609 tANI_U8 tid = 0;
3610 hdd_station_ctx_t *pHddStaCtx = NULL;
3611 tAniTrafStrmMetrics tsmMetrics;
3612 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3613
3614 /* if not associated, return error */
3615 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3616 {
3617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3618 ret = -EINVAL;
3619 goto exit;
3620 }
3621
3622 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3623 value = value + 12;
3624 /* Convert the value from ascii to integer */
3625 ret = kstrtou8(value, 10, &tid);
3626 if (ret < 0)
3627 {
3628 /* If the input value is greater than max value of datatype, then also
3629 kstrtou8 fails */
3630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3631 "%s: kstrtou8 failed range [%d - %d]", __func__,
3632 TID_MIN_VALUE,
3633 TID_MAX_VALUE);
3634 ret = -EINVAL;
3635 goto exit;
3636 }
3637
3638 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3639 {
3640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3641 "tid value %d is out of range"
3642 " (Min: %d Max: %d)", tid,
3643 TID_MIN_VALUE,
3644 TID_MAX_VALUE);
3645 ret = -EINVAL;
3646 goto exit;
3647 }
3648
3649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3650 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3651
3652 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3653 {
3654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3655 "%s: failed to get tsm stats", __func__);
3656 ret = -EFAULT;
3657 goto exit;
3658 }
3659
3660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3661 "UplinkPktQueueDly(%d)\n"
3662 "UplinkPktQueueDlyHist[0](%d)\n"
3663 "UplinkPktQueueDlyHist[1](%d)\n"
3664 "UplinkPktQueueDlyHist[2](%d)\n"
3665 "UplinkPktQueueDlyHist[3](%d)\n"
3666 "UplinkPktTxDly(%lu)\n"
3667 "UplinkPktLoss(%d)\n"
3668 "UplinkPktCount(%d)\n"
3669 "RoamingCount(%d)\n"
3670 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3671 tsmMetrics.UplinkPktQueueDlyHist[0],
3672 tsmMetrics.UplinkPktQueueDlyHist[1],
3673 tsmMetrics.UplinkPktQueueDlyHist[2],
3674 tsmMetrics.UplinkPktQueueDlyHist[3],
3675 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3676 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3677
3678 /* Output TSM stats is of the format
3679 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3680 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003681 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003682 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3683 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3684 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3685 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3686 tsmMetrics.RoamingDly);
3687
3688 if (copy_to_user(priv_data.buf, &extra, len + 1))
3689 {
3690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3691 "%s: failed to copy data to user buffer", __func__);
3692 ret = -EFAULT;
3693 goto exit;
3694 }
3695 }
3696 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3697 {
3698 tANI_U8 *value = command;
3699 tANI_U8 *cckmIe = NULL;
3700 tANI_U8 cckmIeLen = 0;
3701 eHalStatus status = eHAL_STATUS_SUCCESS;
3702
3703 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3704 if (eHAL_STATUS_SUCCESS != status)
3705 {
3706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3707 "%s: Failed to parse cckm ie data", __func__);
3708 ret = -EINVAL;
3709 goto exit;
3710 }
3711
3712 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3713 {
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s: CCKM Ie input length is more than max[%d]", __func__,
3716 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003717 vos_mem_free(cckmIe);
3718 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003719 ret = -EINVAL;
3720 goto exit;
3721 }
3722 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003723 vos_mem_free(cckmIe);
3724 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003725 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003726 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3727 {
3728 tANI_U8 *value = command;
3729 tCsrCcxBeaconReq ccxBcnReq;
3730 eHalStatus status = eHAL_STATUS_SUCCESS;
3731 status = hdd_parse_ccx_beacon_req(value, &ccxBcnReq);
3732 if (eHAL_STATUS_SUCCESS != status)
3733 {
3734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3735 "%s: Failed to parse ccx beacon req", __func__);
3736 ret = -EINVAL;
3737 goto exit;
3738 }
3739
3740 sme_SetCcxBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &ccxBcnReq);
3741 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003742#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003743 else {
3744 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3745 __func__, command);
3746 }
3747
Jeff Johnson295189b2012-06-20 16:38:30 -07003748 }
3749exit:
3750 if (command)
3751 {
3752 kfree(command);
3753 }
3754 return ret;
3755}
3756
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003757
3758
3759#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003760/**---------------------------------------------------------------------------
3761
3762 \brief hdd_parse_ccx_beacon_req() - Parse ccx beacon request
3763
3764 This function parses the ccx beacon request passed in the format
3765 CCXBEACONREQ<space><Number of fields><space><Measurement token>
3766 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
3767 <space>Scan Mode N<space>Meas Duration N
3768 if the Number of bcn req fields (N) does not match with the actual number of fields passed
3769 then take N.
3770 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
3771 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
3772 This function does not take care of removing duplicate channels from the list
3773
3774 \param - pValue Pointer to data
3775 \param - pCcxBcnReq output pointer to store parsed ie information
3776
3777 \return - 0 for success non-zero for failure
3778
3779 --------------------------------------------------------------------------*/
3780static VOS_STATUS hdd_parse_ccx_beacon_req(tANI_U8 *pValue,
3781 tCsrCcxBeaconReq *pCcxBcnReq)
3782{
3783 tANI_U8 *inPtr = pValue;
3784 int tempInt = 0;
3785 int j = 0, i = 0, v = 0;
3786 char buf[32];
3787
3788 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
3789 /*no argument after the command*/
3790 if (NULL == inPtr)
3791 {
3792 return -EINVAL;
3793 }
3794 /*no space after the command*/
3795 else if (SPACE_ASCII_VALUE != *inPtr)
3796 {
3797 return -EINVAL;
3798 }
3799
3800 /*removing empty spaces*/
3801 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3802
3803 /*no argument followed by spaces*/
3804 if ('\0' == *inPtr) return -EINVAL;
3805
3806 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003807 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003808 if (1 != v) return -EINVAL;
3809
3810 v = kstrtos32(buf, 10, &tempInt);
3811 if ( v < 0) return -EINVAL;
3812
3813 pCcxBcnReq->numBcnReqIe = tempInt;
3814
3815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
3816 "Number of Bcn Req Ie fields(%d)", pCcxBcnReq->numBcnReqIe);
3817
3818 for (j = 0; j < (pCcxBcnReq->numBcnReqIe); j++)
3819 {
3820 for (i = 0; i < 4; i++)
3821 {
3822 /*inPtr pointing to the beginning of first space after number of ie fields*/
3823 inPtr = strpbrk( inPtr, " " );
3824 /*no ie data after the number of ie fields argument*/
3825 if (NULL == inPtr) return -EINVAL;
3826
3827 /*removing empty space*/
3828 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
3829
3830 /*no ie data after the number of ie fields argument and spaces*/
3831 if ( '\0' == *inPtr ) return -EINVAL;
3832
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08003833 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003834 if (1 != v) return -EINVAL;
3835
3836 v = kstrtos32(buf, 10, &tempInt);
3837 if (v < 0) return -EINVAL;
3838
3839 switch (i)
3840 {
3841 case 0: /* Measurement token */
3842 if (tempInt <= 0)
3843 {
3844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3845 "Invalid Measurement Token(%d)", tempInt);
3846 return -EINVAL;
3847 }
3848 pCcxBcnReq->bcnReq[j].measurementToken = tempInt;
3849 break;
3850
3851 case 1: /* Channel number */
3852 if ((tempInt <= 0) ||
3853 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
3854 {
3855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3856 "Invalid Channel Number(%d)", tempInt);
3857 return -EINVAL;
3858 }
3859 pCcxBcnReq->bcnReq[j].channel = tempInt;
3860 break;
3861
3862 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003863 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003864 {
3865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3866 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
3867 return -EINVAL;
3868 }
3869 pCcxBcnReq->bcnReq[j].scanMode= tempInt;
3870 break;
3871
3872 case 3: /* Measurement duration */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08003873 if (((tempInt <= 0) && (pCcxBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
3874 ((tempInt < 0) && (pCcxBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003875 {
3876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3877 "Invalid Measurement Duration(%d)", tempInt);
3878 return -EINVAL;
3879 }
3880 pCcxBcnReq->bcnReq[j].measurementDuration = tempInt;
3881 break;
3882 }
3883 }
3884 }
3885
3886 for (j = 0; j < pCcxBcnReq->numBcnReqIe; j++)
3887 {
3888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3889 "Index(%d) Measurement Token(%lu)Channel(%lu) Scan Mode(%lu) Measurement Duration(%lu)\n",
3890 j,
3891 pCcxBcnReq->bcnReq[j].measurementToken,
3892 pCcxBcnReq->bcnReq[j].channel,
3893 pCcxBcnReq->bcnReq[j].scanMode,
3894 pCcxBcnReq->bcnReq[j].measurementDuration);
3895 }
3896
3897 return VOS_STATUS_SUCCESS;
3898}
3899
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003900static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
3901{
3902 struct statsContext *pStatsContext = NULL;
3903 hdd_adapter_t *pAdapter = NULL;
3904
3905 if (NULL == pContext)
3906 {
3907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 "%s: Bad param, pContext [%p]",
3909 __func__, pContext);
3910 return;
3911 }
3912
Jeff Johnson72a40512013-12-19 10:14:15 -08003913 /* there is a race condition that exists between this callback
3914 function and the caller since the caller could time out either
3915 before or while this code is executing. we use a spinlock to
3916 serialize these actions */
3917 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003918
3919 pStatsContext = pContext;
3920 pAdapter = pStatsContext->pAdapter;
3921 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
3922 {
3923 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08003924 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003925 hddLog(VOS_TRACE_LEVEL_WARN,
3926 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3927 __func__, pAdapter, pStatsContext->magic);
3928 return;
3929 }
3930
Jeff Johnson72a40512013-12-19 10:14:15 -08003931 /* context is valid so caller is still waiting */
3932
3933 /* paranoia: invalidate the magic */
3934 pStatsContext->magic = 0;
3935
3936 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003937 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
3938 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
3939 tsmMetrics.UplinkPktQueueDlyHist,
3940 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
3941 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
3942 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
3943 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
3944 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
3945 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
3946 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
3947
Jeff Johnson72a40512013-12-19 10:14:15 -08003948 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003949 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08003950
3951 /* serialization is complete */
3952 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003953}
3954
3955
3956
3957static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
3958 tAniTrafStrmMetrics* pTsmMetrics)
3959{
3960 hdd_station_ctx_t *pHddStaCtx = NULL;
3961 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08003962 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003963 long lrc;
3964 struct statsContext context;
3965 hdd_context_t *pHddCtx = NULL;
3966
3967 if (NULL == pAdapter)
3968 {
3969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
3970 return VOS_STATUS_E_FAULT;
3971 }
3972
3973 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3975
3976 /* we are connected prepare our callback context */
3977 init_completion(&context.completion);
3978 context.pAdapter = pAdapter;
3979 context.magic = STATS_CONTEXT_MAGIC;
3980
3981 /* query tsm stats */
3982 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
3983 pHddStaCtx->conn_info.staId[ 0 ],
3984 pHddStaCtx->conn_info.bssId,
3985 &context, pHddCtx->pvosContext, tid);
3986
3987 if (eHAL_STATUS_SUCCESS != hstatus)
3988 {
Jeff Johnson72a40512013-12-19 10:14:15 -08003989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
3990 __func__);
3991 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003992 }
3993 else
3994 {
3995 /* request was sent -- wait for the response */
3996 lrc = wait_for_completion_interruptible_timeout(&context.completion,
3997 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003998 if (lrc <= 0)
3999 {
4000 hddLog(VOS_TRACE_LEVEL_ERROR,
4001 "%s: SME %s while retrieving statistics",
4002 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004003 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004004 }
4005 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004006
Jeff Johnson72a40512013-12-19 10:14:15 -08004007 /* either we never sent a request, we sent a request and received a
4008 response or we sent a request and timed out. if we never sent a
4009 request or if we sent a request and got a response, we want to
4010 clear the magic out of paranoia. if we timed out there is a
4011 race condition such that the callback function could be
4012 executing at the same time we are. of primary concern is if the
4013 callback function had already verified the "magic" but had not
4014 yet set the completion variable when a timeout occurred. we
4015 serialize these activities by invalidating the magic while
4016 holding a shared spinlock which will cause us to block if the
4017 callback is currently executing */
4018 spin_lock(&hdd_context_lock);
4019 context.magic = 0;
4020 spin_unlock(&hdd_context_lock);
4021
4022 if (VOS_STATUS_SUCCESS == vstatus)
4023 {
4024 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4025 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4026 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4027 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4028 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4029 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4030 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4031 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4032 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4033 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4034 }
4035 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004036}
4037#endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4038
Srinivas Girigowdade697412013-02-14 16:31:48 -08004039#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
4040void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4041{
4042 eCsrBand band = -1;
4043 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4044 switch (band)
4045 {
4046 case eCSR_BAND_ALL:
4047 *pBand = WLAN_HDD_UI_BAND_AUTO;
4048 break;
4049
4050 case eCSR_BAND_24:
4051 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4052 break;
4053
4054 case eCSR_BAND_5G:
4055 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4056 break;
4057
4058 default:
4059 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4060 *pBand = -1;
4061 break;
4062 }
4063}
4064
4065/**---------------------------------------------------------------------------
4066
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004067 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4068
4069 This function parses the send action frame data passed in the format
4070 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4071
Srinivas Girigowda56076852013-08-20 14:00:50 -07004072 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004073 \param - pTargetApBssid Pointer to target Ap bssid
4074 \param - pChannel Pointer to the Target AP channel
4075 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4076 \param - pBuf Pointer to data
4077 \param - pBufLen Pointer to data length
4078
4079 \return - 0 for success non-zero for failure
4080
4081 --------------------------------------------------------------------------*/
4082VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4083 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4084{
4085 tANI_U8 *inPtr = pValue;
4086 tANI_U8 *dataEnd;
4087 int tempInt;
4088 int j = 0;
4089 int i = 0;
4090 int v = 0;
4091 tANI_U8 tempBuf[32];
4092 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004093 /* 12 hexa decimal digits, 5 ':' and '\0' */
4094 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004095
4096 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4097 /*no argument after the command*/
4098 if (NULL == inPtr)
4099 {
4100 return -EINVAL;
4101 }
4102
4103 /*no space after the command*/
4104 else if (SPACE_ASCII_VALUE != *inPtr)
4105 {
4106 return -EINVAL;
4107 }
4108
4109 /*removing empty spaces*/
4110 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4111
4112 /*no argument followed by spaces*/
4113 if ('\0' == *inPtr)
4114 {
4115 return -EINVAL;
4116 }
4117
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004118 v = sscanf(inPtr, "%17s", macAddress);
4119 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004120 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4122 "Invalid MAC address or All hex inputs are not read (%d)", v);
4123 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004124 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004125
4126 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4127 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4128 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4129 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4130 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4131 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004132
4133 /* point to the next argument */
4134 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4135 /*no argument after the command*/
4136 if (NULL == inPtr) return -EINVAL;
4137
4138 /*removing empty spaces*/
4139 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4140
4141 /*no argument followed by spaces*/
4142 if ('\0' == *inPtr)
4143 {
4144 return -EINVAL;
4145 }
4146
4147 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004148 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004149 if (1 != v) return -EINVAL;
4150
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004151 v = kstrtos32(tempBuf, 10, &tempInt);
Kiet Lambe150c22013-11-21 16:30:32 +05304152 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
4153 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004154
4155 *pChannel = tempInt;
4156
4157 /* point to the next argument */
4158 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4159 /*no argument after the command*/
4160 if (NULL == inPtr) return -EINVAL;
4161 /*removing empty spaces*/
4162 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4163
4164 /*no argument followed by spaces*/
4165 if ('\0' == *inPtr)
4166 {
4167 return -EINVAL;
4168 }
4169
4170 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004171 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004172 if (1 != v) return -EINVAL;
4173
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004174 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004175 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004176
4177 *pDwellTime = tempInt;
4178
4179 /* point to the next argument */
4180 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4181 /*no argument after the command*/
4182 if (NULL == inPtr) return -EINVAL;
4183 /*removing empty spaces*/
4184 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4185
4186 /*no argument followed by spaces*/
4187 if ('\0' == *inPtr)
4188 {
4189 return -EINVAL;
4190 }
4191
4192 /* find the length of data */
4193 dataEnd = inPtr;
4194 while(('\0' != *dataEnd) )
4195 {
4196 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004197 }
Kiet Lambe150c22013-11-21 16:30:32 +05304198 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004199 if ( *pBufLen <= 0) return -EINVAL;
4200
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004201 /* Allocate the number of bytes based on the number of input characters
4202 whether it is even or odd.
4203 if the number of input characters are even, then we need N/2 byte.
4204 if the number of input characters are odd, then we need do (N+1)/2 to
4205 compensate rounding off.
4206 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4207 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4208 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004209 if (NULL == *pBuf)
4210 {
4211 hddLog(VOS_TRACE_LEVEL_FATAL,
4212 "%s: vos_mem_alloc failed ", __func__);
4213 return -EINVAL;
4214 }
4215
4216 /* the buffer received from the upper layer is character buffer,
4217 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4218 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4219 and f0 in 3rd location */
4220 for (i = 0, j = 0; j < *pBufLen; j += 2)
4221 {
Kiet Lambe150c22013-11-21 16:30:32 +05304222 if( j+1 == *pBufLen)
4223 {
4224 tempByte = hdd_parse_hex(inPtr[j]);
4225 }
4226 else
4227 {
4228 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4229 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004230 (*pBuf)[i++] = tempByte;
4231 }
4232 *pBufLen = i;
4233 return VOS_STATUS_SUCCESS;
4234}
4235
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004236/**---------------------------------------------------------------------------
4237
Srinivas Girigowdade697412013-02-14 16:31:48 -08004238 \brief hdd_parse_channellist() - HDD Parse channel list
4239
4240 This function parses the channel list passed in the format
4241 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004242 if the Number of channels (N) does not match with the actual number of channels passed
4243 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4244 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4245 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4246 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004247
4248 \param - pValue Pointer to input channel list
4249 \param - ChannelList Pointer to local output array to record channel list
4250 \param - pNumChannels Pointer to number of roam scan channels
4251
4252 \return - 0 for success non-zero for failure
4253
4254 --------------------------------------------------------------------------*/
4255VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4256{
4257 tANI_U8 *inPtr = pValue;
4258 int tempInt;
4259 int j = 0;
4260 int v = 0;
4261 char buf[32];
4262
4263 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4264 /*no argument after the command*/
4265 if (NULL == inPtr)
4266 {
4267 return -EINVAL;
4268 }
4269
4270 /*no space after the command*/
4271 else if (SPACE_ASCII_VALUE != *inPtr)
4272 {
4273 return -EINVAL;
4274 }
4275
4276 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004277 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004278
4279 /*no argument followed by spaces*/
4280 if ('\0' == *inPtr)
4281 {
4282 return -EINVAL;
4283 }
4284
4285 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004286 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004287 if (1 != v) return -EINVAL;
4288
Srinivas Girigowdade697412013-02-14 16:31:48 -08004289 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004290 if ((v < 0) ||
4291 (tempInt <= 0) ||
4292 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4293 {
4294 return -EINVAL;
4295 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004296
4297 *pNumChannels = tempInt;
4298
4299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4300 "Number of channels are: %d", *pNumChannels);
4301
4302 for (j = 0; j < (*pNumChannels); j++)
4303 {
4304 /*inPtr pointing to the beginning of first space after number of channels*/
4305 inPtr = strpbrk( inPtr, " " );
4306 /*no channel list after the number of channels argument*/
4307 if (NULL == inPtr)
4308 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004309 if (0 != j)
4310 {
4311 *pNumChannels = j;
4312 return VOS_STATUS_SUCCESS;
4313 }
4314 else
4315 {
4316 return -EINVAL;
4317 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004318 }
4319
4320 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004321 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004322
4323 /*no channel list after the number of channels argument and spaces*/
4324 if ( '\0' == *inPtr )
4325 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004326 if (0 != j)
4327 {
4328 *pNumChannels = j;
4329 return VOS_STATUS_SUCCESS;
4330 }
4331 else
4332 {
4333 return -EINVAL;
4334 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004335 }
4336
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004337 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004338 if (1 != v) return -EINVAL;
4339
Srinivas Girigowdade697412013-02-14 16:31:48 -08004340 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004341 if ((v < 0) ||
4342 (tempInt <= 0) ||
4343 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4344 {
4345 return -EINVAL;
4346 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004347 pChannelList[j] = tempInt;
4348
4349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4350 "Channel %d added to preferred channel list",
4351 pChannelList[j] );
4352 }
4353
Srinivas Girigowdade697412013-02-14 16:31:48 -08004354 return VOS_STATUS_SUCCESS;
4355}
4356
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004357
4358/**---------------------------------------------------------------------------
4359
4360 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4361
4362 This function parses the reasoc command data passed in the format
4363 REASSOC<space><bssid><space><channel>
4364
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004365 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004366 \param - pTargetApBssid Pointer to target Ap bssid
4367 \param - pChannel Pointer to the Target AP channel
4368
4369 \return - 0 for success non-zero for failure
4370
4371 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004372VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4373 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004374{
4375 tANI_U8 *inPtr = pValue;
4376 int tempInt;
4377 int v = 0;
4378 tANI_U8 tempBuf[32];
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004379 /* 12 hexa decimal digits, 5 ':' and '\0' */
4380 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004381
4382 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4383 /*no argument after the command*/
4384 if (NULL == inPtr)
4385 {
4386 return -EINVAL;
4387 }
4388
4389 /*no space after the command*/
4390 else if (SPACE_ASCII_VALUE != *inPtr)
4391 {
4392 return -EINVAL;
4393 }
4394
4395 /*removing empty spaces*/
4396 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4397
4398 /*no argument followed by spaces*/
4399 if ('\0' == *inPtr)
4400 {
4401 return -EINVAL;
4402 }
4403
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004404 v = sscanf(inPtr, "%17s", macAddress);
4405 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004406 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4408 "Invalid MAC address or All hex inputs are not read (%d)", v);
4409 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004410 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004411
4412 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4413 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4414 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4415 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4416 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4417 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004418
4419 /* point to the next argument */
4420 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4421 /*no argument after the command*/
4422 if (NULL == inPtr) return -EINVAL;
4423
4424 /*removing empty spaces*/
4425 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4426
4427 /*no argument followed by spaces*/
4428 if ('\0' == *inPtr)
4429 {
4430 return -EINVAL;
4431 }
4432
4433 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004434 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004435 if (1 != v) return -EINVAL;
4436
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004437 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004438 if ((v < 0) ||
4439 (tempInt <= 0) ||
4440 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4441 {
4442 return -EINVAL;
4443 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004444
4445 *pChannel = tempInt;
4446 return VOS_STATUS_SUCCESS;
4447}
4448
4449#endif
4450
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004451#if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD)
4452/**---------------------------------------------------------------------------
4453
4454 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4455
4456 This function parses the SETCCKM IE command
4457 SETCCKMIE<space><ie data>
4458
4459 \param - pValue Pointer to input data
4460 \param - pCckmIe Pointer to output cckm Ie
4461 \param - pCckmIeLen Pointer to output cckm ie length
4462
4463 \return - 0 for success non-zero for failure
4464
4465 --------------------------------------------------------------------------*/
4466VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4467 tANI_U8 *pCckmIeLen)
4468{
4469 tANI_U8 *inPtr = pValue;
4470 tANI_U8 *dataEnd;
4471 int j = 0;
4472 int i = 0;
4473 tANI_U8 tempByte = 0;
4474
4475 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4476 /*no argument after the command*/
4477 if (NULL == inPtr)
4478 {
4479 return -EINVAL;
4480 }
4481
4482 /*no space after the command*/
4483 else if (SPACE_ASCII_VALUE != *inPtr)
4484 {
4485 return -EINVAL;
4486 }
4487
4488 /*removing empty spaces*/
4489 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4490
4491 /*no argument followed by spaces*/
4492 if ('\0' == *inPtr)
4493 {
4494 return -EINVAL;
4495 }
4496
4497 /* find the length of data */
4498 dataEnd = inPtr;
4499 while(('\0' != *dataEnd) )
4500 {
4501 dataEnd++;
4502 ++(*pCckmIeLen);
4503 }
4504 if ( *pCckmIeLen <= 0) return -EINVAL;
4505
4506 /* Allocate the number of bytes based on the number of input characters
4507 whether it is even or odd.
4508 if the number of input characters are even, then we need N/2 byte.
4509 if the number of input characters are odd, then we need do (N+1)/2 to
4510 compensate rounding off.
4511 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4512 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4513 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4514 if (NULL == *pCckmIe)
4515 {
4516 hddLog(VOS_TRACE_LEVEL_FATAL,
4517 "%s: vos_mem_alloc failed ", __func__);
4518 return -EINVAL;
4519 }
4520 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4521 /* the buffer received from the upper layer is character buffer,
4522 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4523 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4524 and f0 in 3rd location */
4525 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4526 {
4527 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4528 (*pCckmIe)[i++] = tempByte;
4529 }
4530 *pCckmIeLen = i;
4531
4532 return VOS_STATUS_SUCCESS;
4533}
4534#endif /* FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */
4535
Jeff Johnson295189b2012-06-20 16:38:30 -07004536/**---------------------------------------------------------------------------
4537
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004538 \brief hdd_is_valid_mac_address() - Validate MAC address
4539
4540 This function validates whether the given MAC address is valid or not
4541 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4542 where X is the hexa decimal digit character and separated by ':'
4543 This algorithm works even if MAC address is not separated by ':'
4544
4545 This code checks given input string mac contains exactly 12 hexadecimal digits.
4546 and a separator colon : appears in the input string only after
4547 an even number of hex digits.
4548
4549 \param - pMacAddr pointer to the input MAC address
4550 \return - 1 for valid and 0 for invalid
4551
4552 --------------------------------------------------------------------------*/
4553
4554v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4555{
4556 int xdigit = 0;
4557 int separator = 0;
4558 while (*pMacAddr)
4559 {
4560 if (isxdigit(*pMacAddr))
4561 {
4562 xdigit++;
4563 }
4564 else if (':' == *pMacAddr)
4565 {
4566 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4567 break;
4568
4569 ++separator;
4570 }
4571 else
4572 {
4573 separator = -1;
4574 /* Invalid MAC found */
4575 return 0;
4576 }
4577 ++pMacAddr;
4578 }
4579 return (xdigit == 12 && (separator == 5 || separator == 0));
4580}
4581
4582/**---------------------------------------------------------------------------
4583
Jeff Johnson295189b2012-06-20 16:38:30 -07004584 \brief hdd_open() - HDD Open function
4585
4586 This is called in response to ifconfig up
4587
4588 \param - dev Pointer to net_device structure
4589
4590 \return - 0 for success non-zero for failure
4591
4592 --------------------------------------------------------------------------*/
4593int hdd_open (struct net_device *dev)
4594{
4595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4596 hdd_context_t *pHddCtx;
4597 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4598 VOS_STATUS status;
4599 v_BOOL_t in_standby = TRUE;
4600
4601 if (NULL == pAdapter)
4602 {
4603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004604 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004605 return -ENODEV;
4606 }
4607
4608 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4609 if (NULL == pHddCtx)
4610 {
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004612 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 return -ENODEV;
4614 }
4615
4616 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4617 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4618 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004619 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4620 {
4621 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304622 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004623 in_standby = FALSE;
4624 break;
4625 }
4626 else
4627 {
4628 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4629 pAdapterNode = pNext;
4630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004631 }
4632
4633 if (TRUE == in_standby)
4634 {
4635 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4636 {
4637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4638 "wlan out of power save", __func__);
4639 return -EINVAL;
4640 }
4641 }
4642
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004643 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004644 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4645 {
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004647 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 /* Enable TX queues only when we are connected */
4649 netif_tx_start_all_queues(dev);
4650 }
4651
4652 return 0;
4653}
4654
4655int hdd_mon_open (struct net_device *dev)
4656{
4657 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4658
4659 if(pAdapter == NULL) {
4660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004661 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004662 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 }
4664
4665 netif_start_queue(dev);
4666
4667 return 0;
4668}
4669/**---------------------------------------------------------------------------
4670
4671 \brief hdd_stop() - HDD stop function
4672
4673 This is called in response to ifconfig down
4674
4675 \param - dev Pointer to net_device structure
4676
4677 \return - 0 for success non-zero for failure
4678
4679 --------------------------------------------------------------------------*/
4680
4681int hdd_stop (struct net_device *dev)
4682{
4683 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4684 hdd_context_t *pHddCtx;
4685 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4686 VOS_STATUS status;
4687 v_BOOL_t enter_standby = TRUE;
4688
4689 ENTER();
4690
4691 if (NULL == pAdapter)
4692 {
4693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004694 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 return -ENODEV;
4696 }
4697
4698 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4699 if (NULL == pHddCtx)
4700 {
4701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004702 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004703 return -ENODEV;
4704 }
4705
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004706 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4708 netif_tx_disable(pAdapter->dev);
4709 netif_carrier_off(pAdapter->dev);
4710
4711
4712 /* SoftAP ifaces should never go in power save mode
4713 making sure same here. */
4714 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4715 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004716 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004717 )
4718 {
4719 /* SoftAP mode, so return from here */
4720 EXIT();
4721 return 0;
4722 }
4723
4724 /* Find if any iface is up then
4725 if any iface is up then can't put device to sleep/ power save mode. */
4726 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4727 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4728 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004729 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4730 {
4731 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304732 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004733 enter_standby = FALSE;
4734 break;
4735 }
4736 else
4737 {
4738 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4739 pAdapterNode = pNext;
4740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004741 }
4742
4743 if (TRUE == enter_standby)
4744 {
4745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
4746 "entering standby", __func__);
4747 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
4748 {
4749 /*log and return success*/
4750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
4751 "wlan in power save", __func__);
4752 }
4753 }
4754
4755 EXIT();
4756 return 0;
4757}
4758
4759/**---------------------------------------------------------------------------
4760
4761 \brief hdd_uninit() - HDD uninit function
4762
4763 This is called during the netdev unregister to uninitialize all data
4764associated with the device
4765
4766 \param - dev Pointer to net_device structure
4767
4768 \return - void
4769
4770 --------------------------------------------------------------------------*/
4771static void hdd_uninit (struct net_device *dev)
4772{
4773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4774
4775 ENTER();
4776
4777 do
4778 {
4779 if (NULL == pAdapter)
4780 {
4781 hddLog(VOS_TRACE_LEVEL_FATAL,
4782 "%s: NULL pAdapter", __func__);
4783 break;
4784 }
4785
4786 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
4787 {
4788 hddLog(VOS_TRACE_LEVEL_FATAL,
4789 "%s: Invalid magic", __func__);
4790 break;
4791 }
4792
4793 if (NULL == pAdapter->pHddCtx)
4794 {
4795 hddLog(VOS_TRACE_LEVEL_FATAL,
4796 "%s: NULL pHddCtx", __func__);
4797 break;
4798 }
4799
4800 if (dev != pAdapter->dev)
4801 {
4802 hddLog(VOS_TRACE_LEVEL_FATAL,
4803 "%s: Invalid device reference", __func__);
4804 /* we haven't validated all cases so let this go for now */
4805 }
4806
4807 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
4808
4809 /* after uninit our adapter structure will no longer be valid */
4810 pAdapter->dev = NULL;
4811 pAdapter->magic = 0;
4812 } while (0);
4813
4814 EXIT();
4815}
4816
4817/**---------------------------------------------------------------------------
4818
4819 \brief hdd_release_firmware() -
4820
4821 This function calls the release firmware API to free the firmware buffer.
4822
4823 \param - pFileName Pointer to the File Name.
4824 pCtx - Pointer to the adapter .
4825
4826
4827 \return - 0 for success, non zero for failure
4828
4829 --------------------------------------------------------------------------*/
4830
4831VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
4832{
4833 VOS_STATUS status = VOS_STATUS_SUCCESS;
4834 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4835 ENTER();
4836
4837
4838 if (!strcmp(WLAN_FW_FILE, pFileName)) {
4839
4840 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
4841
4842 if(pHddCtx->fw) {
4843 release_firmware(pHddCtx->fw);
4844 pHddCtx->fw = NULL;
4845 }
4846 else
4847 status = VOS_STATUS_E_FAILURE;
4848 }
4849 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
4850 if(pHddCtx->nv) {
4851 release_firmware(pHddCtx->nv);
4852 pHddCtx->nv = NULL;
4853 }
4854 else
4855 status = VOS_STATUS_E_FAILURE;
4856
4857 }
4858
4859 EXIT();
4860 return status;
4861}
4862
4863/**---------------------------------------------------------------------------
4864
4865 \brief hdd_request_firmware() -
4866
4867 This function reads the firmware file using the request firmware
4868 API and returns the the firmware data and the firmware file size.
4869
4870 \param - pfileName - Pointer to the file name.
4871 - pCtx - Pointer to the adapter .
4872 - ppfw_data - Pointer to the pointer of the firmware data.
4873 - pSize - Pointer to the file size.
4874
4875 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
4876
4877 --------------------------------------------------------------------------*/
4878
4879
4880VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
4881{
4882 int status;
4883 VOS_STATUS retval = VOS_STATUS_SUCCESS;
4884 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4885 ENTER();
4886
4887 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
4888
4889 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
4890
4891 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
4893 __func__, pfileName);
4894 retval = VOS_STATUS_E_FAILURE;
4895 }
4896
4897 else {
4898 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
4899 *pSize = pHddCtx->fw->size;
4900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
4901 __func__, *pSize);
4902 }
4903 }
4904 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
4905
4906 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
4907
4908 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
4909 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
4910 __func__, pfileName);
4911 retval = VOS_STATUS_E_FAILURE;
4912 }
4913
4914 else {
4915 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
4916 *pSize = pHddCtx->nv->size;
4917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
4918 __func__, *pSize);
4919 }
4920 }
4921
4922 EXIT();
4923 return retval;
4924}
4925/**---------------------------------------------------------------------------
4926 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
4927
4928 This is the function invoked by SME to inform the result of a full power
4929 request issued by HDD
4930
4931 \param - callbackcontext - Pointer to cookie
4932 status - result of request
4933
4934 \return - None
4935
4936--------------------------------------------------------------------------*/
4937void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
4938{
4939 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
4940
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004941 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004942 if(&pHddCtx->full_pwr_comp_var)
4943 {
4944 complete(&pHddCtx->full_pwr_comp_var);
4945 }
4946}
4947
4948/**---------------------------------------------------------------------------
4949
4950 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
4951
4952 This is the function invoked by SME to inform the result of BMPS
4953 request issued by HDD
4954
4955 \param - callbackcontext - Pointer to cookie
4956 status - result of request
4957
4958 \return - None
4959
4960--------------------------------------------------------------------------*/
4961void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
4962{
4963
4964 struct completion *completion_var = (struct completion*) callbackContext;
4965
Arif Hussain6d2a3322013-11-17 19:50:10 -08004966 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004967 if(completion_var != NULL)
4968 {
4969 complete(completion_var);
4970 }
4971}
4972
4973/**---------------------------------------------------------------------------
4974
4975 \brief hdd_get_cfg_file_size() -
4976
4977 This function reads the configuration file using the request firmware
4978 API and returns the configuration file size.
4979
4980 \param - pCtx - Pointer to the adapter .
4981 - pFileName - Pointer to the file name.
4982 - pBufSize - Pointer to the buffer size.
4983
4984 \return - 0 for success, non zero for failure
4985
4986 --------------------------------------------------------------------------*/
4987
4988VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
4989{
4990 int status;
4991 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
4992
4993 ENTER();
4994
4995 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
4996
4997 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
4998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
4999 status = VOS_STATUS_E_FAILURE;
5000 }
5001 else {
5002 *pBufSize = pHddCtx->fw->size;
5003 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5004 release_firmware(pHddCtx->fw);
5005 pHddCtx->fw = NULL;
5006 }
5007
5008 EXIT();
5009 return VOS_STATUS_SUCCESS;
5010}
5011
5012/**---------------------------------------------------------------------------
5013
5014 \brief hdd_read_cfg_file() -
5015
5016 This function reads the configuration file using the request firmware
5017 API and returns the cfg data and the buffer size of the configuration file.
5018
5019 \param - pCtx - Pointer to the adapter .
5020 - pFileName - Pointer to the file name.
5021 - pBuffer - Pointer to the data buffer.
5022 - pBufSize - Pointer to the buffer size.
5023
5024 \return - 0 for success, non zero for failure
5025
5026 --------------------------------------------------------------------------*/
5027
5028VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5029 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5030{
5031 int status;
5032 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5033
5034 ENTER();
5035
5036 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5037
5038 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5039 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5040 return VOS_STATUS_E_FAILURE;
5041 }
5042 else {
5043 if(*pBufSize != pHddCtx->fw->size) {
5044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5045 "file size", __func__);
5046 release_firmware(pHddCtx->fw);
5047 pHddCtx->fw = NULL;
5048 return VOS_STATUS_E_FAILURE;
5049 }
5050 else {
5051 if(pBuffer) {
5052 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5053 }
5054 release_firmware(pHddCtx->fw);
5055 pHddCtx->fw = NULL;
5056 }
5057 }
5058
5059 EXIT();
5060
5061 return VOS_STATUS_SUCCESS;
5062}
5063
5064/**---------------------------------------------------------------------------
5065
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 \brief hdd_set_mac_address() -
5067
5068 This function sets the user specified mac address using
5069 the command ifconfig wlanX hw ether <mac adress>.
5070
5071 \param - dev - Pointer to the net device.
5072 - addr - Pointer to the sockaddr.
5073 \return - 0 for success, non zero for failure
5074
5075 --------------------------------------------------------------------------*/
5076
5077static int hdd_set_mac_address(struct net_device *dev, void *addr)
5078{
5079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5080 struct sockaddr *psta_mac_addr = addr;
5081 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5082
5083 ENTER();
5084
5085 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5086
5087#ifdef HDD_SESSIONIZE
5088 // set the MAC address though the STA ID CFG.
5089 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5090 (v_U8_t *)&pAdapter->macAddressCurrent,
5091 sizeof( pAdapter->macAddressCurrent ),
5092 hdd_set_mac_addr_cb, VOS_FALSE );
5093#endif
5094
5095 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5096
5097 EXIT();
5098 return halStatus;
5099}
5100
5101tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5102{
5103 int i;
5104 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5105 {
5106 if( 0 == (pHddCtx->cfg_ini->intfAddrMask >> i))
5107 break;
5108 }
5109
5110 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5111 return NULL;
5112
5113 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5114 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5115}
5116
5117void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5118{
5119 int i;
5120 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5121 {
5122 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5123 {
5124 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5125 break;
5126 }
5127 }
5128 return;
5129}
5130
5131#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5132 static struct net_device_ops wlan_drv_ops = {
5133 .ndo_open = hdd_open,
5134 .ndo_stop = hdd_stop,
5135 .ndo_uninit = hdd_uninit,
5136 .ndo_start_xmit = hdd_hard_start_xmit,
5137 .ndo_tx_timeout = hdd_tx_timeout,
5138 .ndo_get_stats = hdd_stats,
5139 .ndo_do_ioctl = hdd_ioctl,
5140 .ndo_set_mac_address = hdd_set_mac_address,
5141 .ndo_select_queue = hdd_select_queue,
5142#ifdef WLAN_FEATURE_PACKET_FILTERING
5143#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5144 .ndo_set_rx_mode = hdd_set_multicast_list,
5145#else
5146 .ndo_set_multicast_list = hdd_set_multicast_list,
5147#endif //LINUX_VERSION_CODE
5148#endif
5149 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 static struct net_device_ops wlan_mon_drv_ops = {
5151 .ndo_open = hdd_mon_open,
5152 .ndo_stop = hdd_stop,
5153 .ndo_uninit = hdd_uninit,
5154 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5155 .ndo_tx_timeout = hdd_tx_timeout,
5156 .ndo_get_stats = hdd_stats,
5157 .ndo_do_ioctl = hdd_ioctl,
5158 .ndo_set_mac_address = hdd_set_mac_address,
5159 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005160
5161#endif
5162
5163void hdd_set_station_ops( struct net_device *pWlanDev )
5164{
5165#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 pWlanDev->netdev_ops = &wlan_drv_ops;
5167#else
5168 pWlanDev->open = hdd_open;
5169 pWlanDev->stop = hdd_stop;
5170 pWlanDev->uninit = hdd_uninit;
5171 pWlanDev->hard_start_xmit = NULL;
5172 pWlanDev->tx_timeout = hdd_tx_timeout;
5173 pWlanDev->get_stats = hdd_stats;
5174 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 pWlanDev->set_mac_address = hdd_set_mac_address;
5176#endif
5177}
5178
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005179static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005180{
5181 struct net_device *pWlanDev = NULL;
5182 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005183 /*
5184 * cfg80211 initialization and registration....
5185 */
5186 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5187
Jeff Johnson295189b2012-06-20 16:38:30 -07005188 if(pWlanDev != NULL)
5189 {
5190
5191 //Save the pointer to the net_device in the HDD adapter
5192 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5193
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5195
5196 pAdapter->dev = pWlanDev;
5197 pAdapter->pHddCtx = pHddCtx;
5198 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5199
5200 init_completion(&pAdapter->session_open_comp_var);
5201 init_completion(&pAdapter->session_close_comp_var);
5202 init_completion(&pAdapter->disconnect_comp_var);
5203 init_completion(&pAdapter->linkup_event_var);
5204 init_completion(&pAdapter->cancel_rem_on_chan_var);
5205 init_completion(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07005206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5207 init_completion(&pAdapter->offchannel_tx_event);
5208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005210#ifdef FEATURE_WLAN_TDLS
5211 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005212 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005213 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305214 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005215#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005216 init_completion(&pHddCtx->mc_sus_event_var);
5217 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305218 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005219 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005220 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005221
Rajeev79dbe4c2013-10-05 11:03:42 +05305222#ifdef FEATURE_WLAN_BATCH_SCAN
5223 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5224 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5225 pAdapter->pBatchScanRsp = NULL;
5226 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005227 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Rajeev79dbe4c2013-10-05 11:03:42 +05305228 mutex_init(&pAdapter->hdd_batch_scan_lock);
5229#endif
5230
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 pAdapter->isLinkUpSvcNeeded = FALSE;
5232 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5233 //Init the net_device structure
5234 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5235
5236 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5237 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5238 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5239 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5240
5241 hdd_set_station_ops( pAdapter->dev );
5242
5243 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005244 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5245 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5246 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 /* set pWlanDev's parent to underlying device */
5248 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5249 }
5250
5251 return pAdapter;
5252}
5253
5254VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5255{
5256 struct net_device *pWlanDev = pAdapter->dev;
5257 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5258 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5259 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5260
5261 if( rtnl_lock_held )
5262 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005263 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5265 {
5266 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5267 return VOS_STATUS_E_FAILURE;
5268 }
5269 }
5270 if (register_netdevice(pWlanDev))
5271 {
5272 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5273 return VOS_STATUS_E_FAILURE;
5274 }
5275 }
5276 else
5277 {
5278 if(register_netdev(pWlanDev))
5279 {
5280 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5281 return VOS_STATUS_E_FAILURE;
5282 }
5283 }
5284 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5285
5286 return VOS_STATUS_SUCCESS;
5287}
5288
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005289static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005290{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005291 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005292
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005293 if (NULL == pAdapter)
5294 {
5295 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5296 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005298
5299 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5300 {
5301 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5302 return eHAL_STATUS_NOT_INITIALIZED;
5303 }
5304
5305 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5306
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005307#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005308 /* need to make sure all of our scheduled work has completed.
5309 * This callback is called from MC thread context, so it is safe to
5310 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005311 *
5312 * Even though this is called from MC thread context, if there is a faulty
5313 * work item in the system, that can hang this call forever. So flushing
5314 * this global work queue is not safe; and now we make sure that
5315 * individual work queues are stopped correctly. But the cancel work queue
5316 * is a GPL only API, so the proprietary version of the driver would still
5317 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005318 */
5319 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005320#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005321
5322 /* We can be blocked while waiting for scheduled work to be
5323 * flushed, and the adapter structure can potentially be freed, in
5324 * which case the magic will have been reset. So make sure the
5325 * magic is still good, and hence the adapter structure is still
5326 * valid, before signaling completion */
5327 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5328 {
5329 complete(&pAdapter->session_close_comp_var);
5330 }
5331
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 return eHAL_STATUS_SUCCESS;
5333}
5334
5335VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5336{
5337 struct net_device *pWlanDev = pAdapter->dev;
5338 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5339 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5340 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5341 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5342 int rc = 0;
5343
5344 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005345 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 //Open a SME session for future operation
5347 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005348 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5350 {
5351 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005352 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 halStatus, halStatus );
5354 status = VOS_STATUS_E_FAILURE;
5355 goto error_sme_open;
5356 }
5357
5358 //Block on a completion variable. Can't wait forever though.
5359 rc = wait_for_completion_interruptible_timeout(
5360 &pAdapter->session_open_comp_var,
5361 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
5362 if (!rc)
5363 {
5364 hddLog(VOS_TRACE_LEVEL_FATAL,
5365 "Session is not opened within timeout period code %08d", rc );
5366 status = VOS_STATUS_E_FAILURE;
5367 goto error_sme_open;
5368 }
5369
5370 // Register wireless extensions
5371 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5372 {
5373 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005374 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 halStatus, halStatus );
5376 status = VOS_STATUS_E_FAILURE;
5377 goto error_register_wext;
5378 }
5379 //Safe to register the hard_start_xmit function again
5380#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5381 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5382#else
5383 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5384#endif
5385
5386 //Set the Connection State to Not Connected
5387 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5388
5389 //Set the default operation channel
5390 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5391
5392 /* Make the default Auth Type as OPEN*/
5393 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5394
5395 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5396 {
5397 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005398 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 status, status );
5400 goto error_init_txrx;
5401 }
5402
5403 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5404
5405 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5406 {
5407 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005408 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005409 status, status );
5410 goto error_wmm_init;
5411 }
5412
5413 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5414
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005415#ifdef FEATURE_WLAN_TDLS
5416 if(0 != wlan_hdd_tdls_init(pAdapter))
5417 {
5418 status = VOS_STATUS_E_FAILURE;
5419 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5420 goto error_tdls_init;
5421 }
5422 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5423#endif
5424
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 return VOS_STATUS_SUCCESS;
5426
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005427#ifdef FEATURE_WLAN_TDLS
5428error_tdls_init:
5429 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5430 hdd_wmm_adapter_close(pAdapter);
5431#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005432error_wmm_init:
5433 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5434 hdd_deinit_tx_rx(pAdapter);
5435error_init_txrx:
5436 hdd_UnregisterWext(pWlanDev);
5437error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005438 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 {
5440 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005441 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005443 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 {
5445 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005446 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005447 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005448 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 }
5450}
5451error_sme_open:
5452 return status;
5453}
5454
Jeff Johnson295189b2012-06-20 16:38:30 -07005455void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5456{
5457 hdd_cfg80211_state_t *cfgState;
5458
5459 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5460
5461 if( NULL != cfgState->buf )
5462 {
5463 int rc;
5464 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5465 rc = wait_for_completion_interruptible_timeout(
5466 &pAdapter->tx_action_cnf_event,
5467 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
5468 if(!rc)
5469 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005471 ("ERROR: HDD Wait for Action Confirmation Failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 }
5473 }
5474 return;
5475}
Jeff Johnson295189b2012-06-20 16:38:30 -07005476
5477void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5478{
5479 ENTER();
5480 switch ( pAdapter->device_mode )
5481 {
5482 case WLAN_HDD_INFRA_STATION:
5483 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005484 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 {
5486 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5487 {
5488 hdd_deinit_tx_rx( pAdapter );
5489 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5490 }
5491
5492 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5493 {
5494 hdd_wmm_adapter_close( pAdapter );
5495 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5496 }
5497
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005499#ifdef FEATURE_WLAN_TDLS
5500 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5501 {
5502 wlan_hdd_tdls_exit(pAdapter);
5503 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5504 }
5505#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005506
5507 break;
5508 }
5509
5510 case WLAN_HDD_SOFTAP:
5511 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305513
5514 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5515 {
5516 hdd_wmm_adapter_close( pAdapter );
5517 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5518 }
5519
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005521
5522 hdd_unregister_hostapd(pAdapter);
5523 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 break;
5526 }
5527
5528 case WLAN_HDD_MONITOR:
5529 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005530 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5532 {
5533 hdd_deinit_tx_rx( pAdapter );
5534 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 if(NULL != pAdapterforTx)
5537 {
5538 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5539 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 break;
5541 }
5542
5543
5544 default:
5545 break;
5546 }
5547
5548 EXIT();
5549}
5550
5551void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5552{
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305553 struct net_device *pWlanDev;
5554
5555 ENTER();
5556 if (NULL == pAdapter)
5557 {
5558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5559 "%s: HDD adapter is Null", __func__);
5560 return;
5561 }
5562
5563 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005564
Rajeev79dbe4c2013-10-05 11:03:42 +05305565#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305566 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5567 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005568 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305569 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5570 )
5571 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005572 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305573 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005574 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5575 {
5576 hdd_deinit_batch_scan(pAdapter);
5577 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305578 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005579 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305580#endif
5581
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5583 if( rtnl_held )
5584 {
5585 unregister_netdevice(pWlanDev);
5586 }
5587 else
5588 {
5589 unregister_netdev(pWlanDev);
5590 }
5591 // note that the pAdapter is no longer valid at this point
5592 // since the memory has been reclaimed
5593 }
5594
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305595 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005596}
5597
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005598void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5599{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305600 VOS_STATUS status;
5601 hdd_adapter_t *pAdapter = NULL;
5602 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005603
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305604 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005605
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305606 /*loop through all adapters.*/
5607 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005608 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305609 pAdapter = pAdapterNode->pAdapter;
5610 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5611 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005612
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305613 { // we skip this registration for modes other than STA and P2P client modes.
5614 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5615 pAdapterNode = pNext;
5616 continue;
5617 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005618
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305619 //Apply Dynamic DTIM For P2P
5620 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5621 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5622 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5623 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5624 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5625 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5626 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5627 (eConnectionState_Associated ==
5628 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5629 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5630 {
5631 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005632
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305633 powerRequest.uIgnoreDTIM = 1;
5634 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5635
5636 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5637 {
5638 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5639 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5640 }
5641 else
5642 {
5643 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5644 }
5645
5646 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5647 * specified during Enter/Exit BMPS when LCD off*/
5648 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5649 NULL, eANI_BOOLEAN_FALSE);
5650 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5651 NULL, eANI_BOOLEAN_FALSE);
5652
5653 /* switch to the DTIM specified in cfg.ini */
5654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5655 "Switch to DTIM %d", powerRequest.uListenInterval);
5656 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5657 break;
5658
5659 }
5660
5661 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5662 pAdapterNode = pNext;
5663 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005664}
5665
5666void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5667{
5668 /*Switch back to DTIM 1*/
5669 tSirSetPowerParamsReq powerRequest = { 0 };
5670
5671 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5672 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005673 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005674
5675 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5676 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5677 NULL, eANI_BOOLEAN_FALSE);
5678 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5679 NULL, eANI_BOOLEAN_FALSE);
5680
5681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5682 "Switch to DTIM%d",powerRequest.uListenInterval);
5683 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5684
5685}
5686
Jeff Johnson295189b2012-06-20 16:38:30 -07005687VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5688{
5689 VOS_STATUS status = VOS_STATUS_SUCCESS;
5690
5691 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5692 {
5693 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5694 }
5695
5696 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5697 {
5698 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5699 }
5700
5701 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5702 {
5703 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5704 }
5705
5706 return status;
5707}
5708
5709VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5710{
5711 hdd_adapter_t *pAdapter = NULL;
5712 eHalStatus halStatus;
5713 VOS_STATUS status = VOS_STATUS_E_INVAL;
5714 v_BOOL_t disableBmps = FALSE;
5715 v_BOOL_t disableImps = FALSE;
5716
5717 switch(session_type)
5718 {
5719 case WLAN_HDD_INFRA_STATION:
5720 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 case WLAN_HDD_P2P_CLIENT:
5722 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 //Exit BMPS -> Is Sta/P2P Client is already connected
5724 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
5725 if((NULL != pAdapter)&&
5726 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5727 {
5728 disableBmps = TRUE;
5729 }
5730
5731 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
5732 if((NULL != pAdapter)&&
5733 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5734 {
5735 disableBmps = TRUE;
5736 }
5737
5738 //Exit both Bmps and Imps incase of Go/SAP Mode
5739 if((WLAN_HDD_SOFTAP == session_type) ||
5740 (WLAN_HDD_P2P_GO == session_type))
5741 {
5742 disableBmps = TRUE;
5743 disableImps = TRUE;
5744 }
5745
5746 if(TRUE == disableImps)
5747 {
5748 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5749 {
5750 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5751 }
5752 }
5753
5754 if(TRUE == disableBmps)
5755 {
5756 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5757 {
5758 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5759
5760 if(eHAL_STATUS_SUCCESS != halStatus)
5761 {
5762 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005763 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 VOS_ASSERT(0);
5765 return status;
5766 }
5767 }
5768
5769 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5770 {
5771 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
5772
5773 if(eHAL_STATUS_SUCCESS != halStatus)
5774 {
5775 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005776 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 VOS_ASSERT(0);
5778 return status;
5779 }
5780 }
5781 }
5782
5783 if((TRUE == disableBmps) ||
5784 (TRUE == disableImps))
5785 {
5786 /* Now, get the chip into Full Power now */
5787 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
5788 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
5789 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
5790
5791 if(halStatus != eHAL_STATUS_SUCCESS)
5792 {
5793 if(halStatus == eHAL_STATUS_PMC_PENDING)
5794 {
5795 //Block on a completion variable. Can't wait forever though
5796 wait_for_completion_interruptible_timeout(
5797 &pHddCtx->full_pwr_comp_var, msecs_to_jiffies(1000));
5798 }
5799 else
5800 {
5801 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08005802 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 VOS_ASSERT(0);
5804 return status;
5805 }
5806 }
5807
5808 status = VOS_STATUS_SUCCESS;
5809 }
5810
5811 break;
5812 }
5813 return status;
5814}
5815
5816hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005817 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 tANI_U8 rtnl_held )
5819{
5820 hdd_adapter_t *pAdapter = NULL;
5821 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
5822 VOS_STATUS status = VOS_STATUS_E_FAILURE;
5823 VOS_STATUS exitbmpsStatus;
5824
Arif Hussain6d2a3322013-11-17 19:50:10 -08005825 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07005826
5827 //Disable BMPS incase of Concurrency
5828 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
5829
5830 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
5831 {
5832 //Fail to Exit BMPS
5833 VOS_ASSERT(0);
5834 return NULL;
5835 }
5836
5837 switch(session_type)
5838 {
5839 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005841 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 {
5843 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5844
5845 if( NULL == pAdapter )
5846 return NULL;
5847
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305848#ifdef FEATURE_WLAN_TDLS
5849 /* A Mutex Lock is introduced while changing/initializing the mode to
5850 * protect the concurrent access for the Adapters by TDLS module.
5851 */
5852 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
5853 {
5854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5855 "%s: unable to lock list", __func__);
5856 return NULL;
5857 }
5858#endif
5859
Jeff Johnsone7245742012-09-05 17:12:55 -07005860 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
5861 NL80211_IFTYPE_P2P_CLIENT:
5862 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07005863
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05305865#ifdef FEATURE_WLAN_TDLS
5866 mutex_unlock(&pHddCtx->tdls_lock);
5867#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05305868
5869 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 if( VOS_STATUS_SUCCESS != status )
5871 goto err_free_netdev;
5872
5873 status = hdd_register_interface( pAdapter, rtnl_held );
5874 if( VOS_STATUS_SUCCESS != status )
5875 {
5876 hdd_deinit_adapter(pHddCtx, pAdapter);
5877 goto err_free_netdev;
5878 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305879
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05305880 // Workqueue which gets scheduled in IPv4 notification callback.
5881 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
5882
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05305883#ifdef WLAN_NS_OFFLOAD
5884 // Workqueue which gets scheduled in IPv6 notification callback.
5885 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
5886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 //Stop the Interface TX queue.
5888 netif_tx_disable(pAdapter->dev);
5889 //netif_tx_disable(pWlanDev);
5890 netif_carrier_off(pAdapter->dev);
5891
5892 break;
5893 }
5894
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 case WLAN_HDD_SOFTAP:
5897 {
5898 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
5899 if( NULL == pAdapter )
5900 return NULL;
5901
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
5903 NL80211_IFTYPE_AP:
5904 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 pAdapter->device_mode = session_type;
5906
5907 status = hdd_init_ap_mode(pAdapter);
5908 if( VOS_STATUS_SUCCESS != status )
5909 goto err_free_netdev;
5910
5911 status = hdd_register_hostapd( pAdapter, rtnl_held );
5912 if( VOS_STATUS_SUCCESS != status )
5913 {
5914 hdd_deinit_adapter(pHddCtx, pAdapter);
5915 goto err_free_netdev;
5916 }
5917
5918 netif_tx_disable(pAdapter->dev);
5919 netif_carrier_off(pAdapter->dev);
5920
5921 hdd_set_conparam( 1 );
5922 break;
5923 }
5924 case WLAN_HDD_MONITOR:
5925 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5927 if( NULL == pAdapter )
5928 return NULL;
5929
5930 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
5931 pAdapter->device_mode = session_type;
5932 status = hdd_register_interface( pAdapter, rtnl_held );
5933#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
5934 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
5935#else
5936 pAdapter->dev->open = hdd_mon_open;
5937 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
5938#endif
5939 hdd_init_tx_rx( pAdapter );
5940 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5941 //Set adapter to be used for data tx. It will use either GO or softap.
5942 pAdapter->sessionCtx.monitor.pAdapterForTx =
5943 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
5945 {
5946 pAdapter->sessionCtx.monitor.pAdapterForTx =
5947 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
5948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 /* This workqueue will be used to transmit management packet over
5950 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005951 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
5952 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
5953 return NULL;
5954 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07005955
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
5957 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 }
5959 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 case WLAN_HDD_FTM:
5961 {
5962 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
5963
5964 if( NULL == pAdapter )
5965 return NULL;
5966 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
5967 * message while loading driver in FTM mode. */
5968 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
5969 pAdapter->device_mode = session_type;
5970 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05305971
5972 hdd_init_tx_rx( pAdapter );
5973
5974 //Stop the Interface TX queue.
5975 netif_tx_disable(pAdapter->dev);
5976 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 }
5978 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 default:
5980 {
5981 VOS_ASSERT(0);
5982 return NULL;
5983 }
5984 }
5985
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 if( VOS_STATUS_SUCCESS == status )
5987 {
5988 //Add it to the hdd's session list.
5989 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
5990 if( NULL == pHddAdapterNode )
5991 {
5992 status = VOS_STATUS_E_NOMEM;
5993 }
5994 else
5995 {
5996 pHddAdapterNode->pAdapter = pAdapter;
5997 status = hdd_add_adapter_back ( pHddCtx,
5998 pHddAdapterNode );
5999 }
6000 }
6001
6002 if( VOS_STATUS_SUCCESS != status )
6003 {
6004 if( NULL != pAdapter )
6005 {
6006 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6007 pAdapter = NULL;
6008 }
6009 if( NULL != pHddAdapterNode )
6010 {
6011 vos_mem_free( pHddAdapterNode );
6012 }
6013
6014 goto resume_bmps;
6015 }
6016
6017 if(VOS_STATUS_SUCCESS == status)
6018 {
6019 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6020
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006021 //Initialize the WoWL service
6022 if(!hdd_init_wowl(pAdapter))
6023 {
6024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6025 goto err_free_netdev;
6026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 return pAdapter;
6029
6030err_free_netdev:
6031 free_netdev(pAdapter->dev);
6032 wlan_hdd_release_intf_addr( pHddCtx,
6033 pAdapter->macAddressCurrent.bytes );
6034
6035resume_bmps:
6036 //If bmps disabled enable it
6037 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6038 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306039 if (pHddCtx->hdd_wlan_suspended)
6040 {
6041 hdd_set_pwrparams(pHddCtx);
6042 }
6043 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 }
6045 return NULL;
6046}
6047
6048VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6049 tANI_U8 rtnl_held )
6050{
6051 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6052 VOS_STATUS status;
6053
6054 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6055 if( VOS_STATUS_SUCCESS != status )
6056 return status;
6057
6058 while ( pCurrent->pAdapter != pAdapter )
6059 {
6060 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6061 if( VOS_STATUS_SUCCESS != status )
6062 break;
6063
6064 pCurrent = pNext;
6065 }
6066 pAdapterNode = pCurrent;
6067 if( VOS_STATUS_SUCCESS == status )
6068 {
6069 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6070 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306071
6072#ifdef FEATURE_WLAN_TDLS
6073
6074 /* A Mutex Lock is introduced while changing/initializing the mode to
6075 * protect the concurrent access for the Adapters by TDLS module.
6076 */
6077 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
6078 {
6079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6080 "%s: unable to lock list", __func__);
6081 return VOS_STATUS_E_FAILURE;
6082 }
6083#endif
6084
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 hdd_remove_adapter( pHddCtx, pAdapterNode );
6086 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006087 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006088
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306089#ifdef FEATURE_WLAN_TDLS
6090 mutex_unlock(&pHddCtx->tdls_lock);
6091#endif
6092
Jeff Johnson295189b2012-06-20 16:38:30 -07006093
6094 /* If there is a single session of STA/P2P client, re-enable BMPS */
6095 if ((!vos_concurrent_sessions_running()) &&
6096 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6097 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6098 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306099 if (pHddCtx->hdd_wlan_suspended)
6100 {
6101 hdd_set_pwrparams(pHddCtx);
6102 }
6103 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 }
6105
6106 return VOS_STATUS_SUCCESS;
6107 }
6108
6109 return VOS_STATUS_E_FAILURE;
6110}
6111
6112VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6113{
6114 hdd_adapter_list_node_t *pHddAdapterNode;
6115 VOS_STATUS status;
6116
6117 ENTER();
6118
6119 do
6120 {
6121 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6122 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6123 {
6124 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6125 vos_mem_free( pHddAdapterNode );
6126 }
6127 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6128
6129 EXIT();
6130
6131 return VOS_STATUS_SUCCESS;
6132}
6133
6134void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6135{
6136 v_U8_t addIE[1] = {0};
6137
6138 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6139 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6140 eANI_BOOLEAN_FALSE) )
6141 {
6142 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006143 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 }
6145
6146 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6147 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6148 eANI_BOOLEAN_FALSE) )
6149 {
6150 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006151 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 }
6153
6154 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6155 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6156 eANI_BOOLEAN_FALSE) )
6157 {
6158 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006159 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 }
6161}
6162
6163VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6164{
6165 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6167 union iwreq_data wrqu;
6168
6169 ENTER();
6170
6171 switch(pAdapter->device_mode)
6172 {
6173 case WLAN_HDD_INFRA_STATION:
6174 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006175 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6177 {
6178 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6179 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6180 pAdapter->sessionId,
6181 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6182 else
6183 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6184 pAdapter->sessionId,
6185 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6186 //success implies disconnect command got queued up successfully
6187 if(halStatus == eHAL_STATUS_SUCCESS)
6188 {
6189 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
6190 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6191 }
6192 memset(&wrqu, '\0', sizeof(wrqu));
6193 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6194 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6195 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6196 }
6197 else
6198 {
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05306199 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306201#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306202#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306203 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6204#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306205 if (pAdapter->ipv6_notifier_registered)
6206 {
6207 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6208 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6209 pAdapter->ipv6_notifier_registered = false;
6210 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306211#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306212 if (pAdapter->ipv4_notifier_registered)
6213 {
6214 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6215 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6216 pAdapter->ipv4_notifier_registered = false;
6217 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306218#ifdef WLAN_OPEN_SOURCE
6219 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6220#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6222 {
6223 INIT_COMPLETION(pAdapter->session_close_comp_var);
6224 if (eHAL_STATUS_SUCCESS ==
6225 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6226 hdd_smeCloseSessionCallback, pAdapter))
6227 {
6228 //Block on a completion variable. Can't wait forever though.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006229 wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 &pAdapter->session_close_comp_var,
6231 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
6232 }
6233 }
6234
6235 break;
6236
6237 case WLAN_HDD_SOFTAP:
6238 case WLAN_HDD_P2P_GO:
6239 //Any softap specific cleanup here...
6240 mutex_lock(&pHddCtx->sap_lock);
6241 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6242 {
6243 VOS_STATUS status;
6244 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6245
6246 //Stop Bss.
6247 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6248 if (VOS_IS_STATUS_SUCCESS(status))
6249 {
6250 hdd_hostapd_state_t *pHostapdState =
6251 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6252
6253 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6254
6255 if (!VOS_IS_STATUS_SUCCESS(status))
6256 {
6257 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006258 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006259 }
6260 }
6261 else
6262 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006263 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 }
6265 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6266
6267 if (eHAL_STATUS_FAILURE ==
6268 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6269 0, NULL, eANI_BOOLEAN_FALSE))
6270 {
6271 hddLog(LOGE,
6272 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006273 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 }
6275
6276 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6277 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6278 eANI_BOOLEAN_FALSE) )
6279 {
6280 hddLog(LOGE,
6281 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6282 }
6283
6284 // Reset WNI_CFG_PROBE_RSP Flags
6285 wlan_hdd_reset_prob_rspies(pAdapter);
6286 kfree(pAdapter->sessionCtx.ap.beacon);
6287 pAdapter->sessionCtx.ap.beacon = NULL;
6288 }
6289 mutex_unlock(&pHddCtx->sap_lock);
6290 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006291
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006293#ifdef WLAN_OPEN_SOURCE
6294 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6295#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006297
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 default:
6299 break;
6300 }
6301
6302 EXIT();
6303 return VOS_STATUS_SUCCESS;
6304}
6305
6306VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6307{
6308 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6309 VOS_STATUS status;
6310 hdd_adapter_t *pAdapter;
6311
6312 ENTER();
6313
6314 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6315
6316 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6317 {
6318 pAdapter = pAdapterNode->pAdapter;
6319 netif_tx_disable(pAdapter->dev);
6320 netif_carrier_off(pAdapter->dev);
6321
6322 hdd_stop_adapter( pHddCtx, pAdapter );
6323
6324 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6325 pAdapterNode = pNext;
6326 }
6327
6328 EXIT();
6329
6330 return VOS_STATUS_SUCCESS;
6331}
6332
Rajeev Kumarf999e582014-01-09 17:33:29 -08006333
6334#ifdef FEATURE_WLAN_BATCH_SCAN
6335/**---------------------------------------------------------------------------
6336
6337 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6338 structures
6339
6340 \param - pAdapter Pointer to HDD adapter
6341
6342 \return - None
6343
6344 --------------------------------------------------------------------------*/
6345void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6346{
6347 tHddBatchScanRsp *pNode;
6348 tHddBatchScanRsp *pPrev;
6349
6350 if (pAdapter)
6351 {
6352 pNode = pAdapter->pBatchScanRsp;
6353 while (pNode)
6354 {
6355 pPrev = pNode;
6356 pNode = pNode->pNext;
6357 vos_mem_free((v_VOID_t * )pPrev);
6358 }
6359 pAdapter->pBatchScanRsp = NULL;
6360 }
6361
6362 pAdapter->pBatchScanRsp = NULL;
6363 pAdapter->numScanList = 0;
6364 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6365 pAdapter->prev_batch_id = 0;
6366
6367 return;
6368}
6369#endif
6370
6371
Jeff Johnson295189b2012-06-20 16:38:30 -07006372VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6373{
6374 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6375 VOS_STATUS status;
6376 hdd_adapter_t *pAdapter;
6377
6378 ENTER();
6379
6380 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6381
6382 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6383 {
6384 pAdapter = pAdapterNode->pAdapter;
6385 netif_tx_disable(pAdapter->dev);
6386 netif_carrier_off(pAdapter->dev);
6387
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006388 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6389
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306391 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6392 {
6393 hdd_wmm_adapter_close( pAdapter );
6394 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006396
Rajeev Kumarf999e582014-01-09 17:33:29 -08006397#ifdef FEATURE_WLAN_BATCH_SCAN
6398 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6399 {
6400 hdd_deinit_batch_scan(pAdapter);
6401 }
6402#endif
6403
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6405 pAdapterNode = pNext;
6406 }
6407
6408 EXIT();
6409
6410 return VOS_STATUS_SUCCESS;
6411}
6412
6413VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6414{
6415 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6416 VOS_STATUS status;
6417 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306418 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006419
6420 ENTER();
6421
6422 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6423
6424 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6425 {
6426 pAdapter = pAdapterNode->pAdapter;
6427
6428 switch(pAdapter->device_mode)
6429 {
6430 case WLAN_HDD_INFRA_STATION:
6431 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006432 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306433
6434 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 hdd_init_station_mode(pAdapter);
6437 /* Open the gates for HDD to receive Wext commands */
6438 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006439 pHddCtx->scan_info.mScanPending = FALSE;
6440 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441
6442 //Trigger the initial scan
6443 hdd_wlan_initial_scan(pAdapter);
6444
6445 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306446 if (eConnectionState_Associated == connState ||
6447 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 {
6449 union iwreq_data wrqu;
6450 memset(&wrqu, '\0', sizeof(wrqu));
6451 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6452 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6453 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006454 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006455
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 /* indicate disconnected event to nl80211 */
6457 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6458 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306460 else if (eConnectionState_Connecting == connState)
6461 {
6462 /*
6463 * Indicate connect failure to supplicant if we were in the
6464 * process of connecting
6465 */
6466 cfg80211_connect_result(pAdapter->dev, NULL,
6467 NULL, 0, NULL, 0,
6468 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6469 GFP_KERNEL);
6470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 break;
6472
6473 case WLAN_HDD_SOFTAP:
6474 /* softAP can handle SSR */
6475 break;
6476
6477 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006480 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 break;
6482
6483 case WLAN_HDD_MONITOR:
6484 /* monitor interface start */
6485 break;
6486 default:
6487 break;
6488 }
6489
6490 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6491 pAdapterNode = pNext;
6492 }
6493
6494 EXIT();
6495
6496 return VOS_STATUS_SUCCESS;
6497}
6498
6499VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6500{
6501 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6502 hdd_adapter_t *pAdapter;
6503 VOS_STATUS status;
6504 v_U32_t roamId;
6505
6506 ENTER();
6507
6508 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6509
6510 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6511 {
6512 pAdapter = pAdapterNode->pAdapter;
6513
6514 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6515 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6516 {
6517 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6518 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6519
6520 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6521 init_completion(&pAdapter->disconnect_comp_var);
6522 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6523 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6524
6525 wait_for_completion_interruptible_timeout(
6526 &pAdapter->disconnect_comp_var,
6527 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6528
6529 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6530 pHddCtx->isAmpAllowed = VOS_FALSE;
6531 sme_RoamConnect(pHddCtx->hHal,
6532 pAdapter->sessionId, &(pWextState->roamProfile),
6533 &roamId);
6534 }
6535
6536 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6537 pAdapterNode = pNext;
6538 }
6539
6540 EXIT();
6541
6542 return VOS_STATUS_SUCCESS;
6543}
6544
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006545void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6546{
6547 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6548 VOS_STATUS status;
6549 hdd_adapter_t *pAdapter;
6550 hdd_station_ctx_t *pHddStaCtx;
6551 hdd_ap_ctx_t *pHddApCtx;
6552 hdd_hostapd_state_t * pHostapdState;
6553 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6554 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6555 const char *p2pMode = "DEV";
6556 const char *ccMode = "Standalone";
6557 int n;
6558
6559 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6560 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6561 {
6562 pAdapter = pAdapterNode->pAdapter;
6563 switch (pAdapter->device_mode) {
6564 case WLAN_HDD_INFRA_STATION:
6565 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6566 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6567 staChannel = pHddStaCtx->conn_info.operationChannel;
6568 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6569 }
6570 break;
6571 case WLAN_HDD_P2P_CLIENT:
6572 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6573 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6574 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6575 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6576 p2pMode = "CLI";
6577 }
6578 break;
6579 case WLAN_HDD_P2P_GO:
6580 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6581 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6582 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6583 p2pChannel = pHddApCtx->operatingChannel;
6584 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6585 }
6586 p2pMode = "GO";
6587 break;
6588 case WLAN_HDD_SOFTAP:
6589 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6590 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6591 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6592 apChannel = pHddApCtx->operatingChannel;
6593 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6594 }
6595 break;
6596 default:
6597 break;
6598 }
6599 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6600 pAdapterNode = pNext;
6601 }
6602 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
6603 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
6604 }
6605 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
6606 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
6607 if (p2pChannel > 0) {
6608 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
6609 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
6610 }
6611 if (apChannel > 0) {
6612 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
6613 apChannel, MAC_ADDR_ARRAY(apBssid));
6614 }
6615
6616 if (p2pChannel > 0 && apChannel > 0) {
6617 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
6618 }
6619}
6620
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006621bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07006622{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006623 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07006624}
6625
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006626/* Once SSR is disabled then it cannot be set. */
6627void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07006628{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07006629 if (HDD_SSR_DISABLED == isSsrRequired)
6630 return;
6631
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 isSsrRequired = value;
6633}
6634
6635VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
6636 hdd_adapter_list_node_t** ppAdapterNode)
6637{
6638 VOS_STATUS status;
6639 spin_lock(&pHddCtx->hddAdapters.lock);
6640 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
6641 (hdd_list_node_t**) ppAdapterNode );
6642 spin_unlock(&pHddCtx->hddAdapters.lock);
6643 return status;
6644}
6645
6646VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
6647 hdd_adapter_list_node_t* pAdapterNode,
6648 hdd_adapter_list_node_t** pNextAdapterNode)
6649{
6650 VOS_STATUS status;
6651 spin_lock(&pHddCtx->hddAdapters.lock);
6652 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
6653 (hdd_list_node_t*) pAdapterNode,
6654 (hdd_list_node_t**)pNextAdapterNode );
6655
6656 spin_unlock(&pHddCtx->hddAdapters.lock);
6657 return status;
6658}
6659
6660VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
6661 hdd_adapter_list_node_t* pAdapterNode)
6662{
6663 VOS_STATUS status;
6664 spin_lock(&pHddCtx->hddAdapters.lock);
6665 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
6666 &pAdapterNode->node );
6667 spin_unlock(&pHddCtx->hddAdapters.lock);
6668 return status;
6669}
6670
6671VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
6672 hdd_adapter_list_node_t** ppAdapterNode)
6673{
6674 VOS_STATUS status;
6675 spin_lock(&pHddCtx->hddAdapters.lock);
6676 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
6677 (hdd_list_node_t**) ppAdapterNode );
6678 spin_unlock(&pHddCtx->hddAdapters.lock);
6679 return status;
6680}
6681
6682VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
6683 hdd_adapter_list_node_t* pAdapterNode)
6684{
6685 VOS_STATUS status;
6686 spin_lock(&pHddCtx->hddAdapters.lock);
6687 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
6688 (hdd_list_node_t*) pAdapterNode );
6689 spin_unlock(&pHddCtx->hddAdapters.lock);
6690 return status;
6691}
6692
6693VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
6694 hdd_adapter_list_node_t* pAdapterNode)
6695{
6696 VOS_STATUS status;
6697 spin_lock(&pHddCtx->hddAdapters.lock);
6698 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
6699 (hdd_list_node_t*) pAdapterNode );
6700 spin_unlock(&pHddCtx->hddAdapters.lock);
6701 return status;
6702}
6703
6704hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
6705 tSirMacAddr macAddr )
6706{
6707 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6708 hdd_adapter_t *pAdapter;
6709 VOS_STATUS status;
6710
6711 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6712
6713 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6714 {
6715 pAdapter = pAdapterNode->pAdapter;
6716
6717 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
6718 macAddr, sizeof(tSirMacAddr) ) )
6719 {
6720 return pAdapter;
6721 }
6722 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6723 pAdapterNode = pNext;
6724 }
6725
6726 return NULL;
6727
6728}
6729
6730hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
6731{
6732 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6733 hdd_adapter_t *pAdapter;
6734 VOS_STATUS status;
6735
6736 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6737
6738 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6739 {
6740 pAdapter = pAdapterNode->pAdapter;
6741
6742 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
6743 IFNAMSIZ ) )
6744 {
6745 return pAdapter;
6746 }
6747 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6748 pAdapterNode = pNext;
6749 }
6750
6751 return NULL;
6752
6753}
6754
6755hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
6756{
6757 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6758 hdd_adapter_t *pAdapter;
6759 VOS_STATUS status;
6760
6761 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6762
6763 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6764 {
6765 pAdapter = pAdapterNode->pAdapter;
6766
6767 if( pAdapter && (mode == pAdapter->device_mode) )
6768 {
6769 return pAdapter;
6770 }
6771 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6772 pAdapterNode = pNext;
6773 }
6774
6775 return NULL;
6776
6777}
6778
6779//Remove this function later
6780hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
6781{
6782 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6783 hdd_adapter_t *pAdapter;
6784 VOS_STATUS status;
6785
6786 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6787
6788 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6789 {
6790 pAdapter = pAdapterNode->pAdapter;
6791
6792 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
6793 {
6794 return pAdapter;
6795 }
6796
6797 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6798 pAdapterNode = pNext;
6799 }
6800
6801 return NULL;
6802
6803}
6804
Jeff Johnson295189b2012-06-20 16:38:30 -07006805/**---------------------------------------------------------------------------
6806
6807 \brief hdd_set_monitor_tx_adapter() -
6808
6809 This API initializes the adapter to be used while transmitting on monitor
6810 adapter.
6811
6812 \param - pHddCtx - Pointer to the HDD context.
6813 pAdapter - Adapter that will used for TX. This can be NULL.
6814 \return - None.
6815 --------------------------------------------------------------------------*/
6816void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6817{
6818 hdd_adapter_t *pMonAdapter;
6819
6820 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
6821
6822 if( NULL != pMonAdapter )
6823 {
6824 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
6825 }
6826}
Jeff Johnson295189b2012-06-20 16:38:30 -07006827/**---------------------------------------------------------------------------
6828
6829 \brief hdd_select_queue() -
6830
6831 This API returns the operating channel of the requested device mode
6832
6833 \param - pHddCtx - Pointer to the HDD context.
6834 - mode - Device mode for which operating channel is required
6835 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
6836 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
6837 \return - channel number. "0" id the requested device is not found OR it is not connected.
6838 --------------------------------------------------------------------------*/
6839v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
6840{
6841 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6842 VOS_STATUS status;
6843 hdd_adapter_t *pAdapter;
6844 v_U8_t operatingChannel = 0;
6845
6846 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6847
6848 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6849 {
6850 pAdapter = pAdapterNode->pAdapter;
6851
6852 if( mode == pAdapter->device_mode )
6853 {
6854 switch(pAdapter->device_mode)
6855 {
6856 case WLAN_HDD_INFRA_STATION:
6857 case WLAN_HDD_P2P_CLIENT:
6858 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
6859 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
6860 break;
6861 case WLAN_HDD_SOFTAP:
6862 case WLAN_HDD_P2P_GO:
6863 /*softap connection info */
6864 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6865 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
6866 break;
6867 default:
6868 break;
6869 }
6870
6871 break; //Found the device of interest. break the loop
6872 }
6873
6874 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6875 pAdapterNode = pNext;
6876 }
6877 return operatingChannel;
6878}
6879
6880#ifdef WLAN_FEATURE_PACKET_FILTERING
6881/**---------------------------------------------------------------------------
6882
6883 \brief hdd_set_multicast_list() -
6884
6885 This used to set the multicast address list.
6886
6887 \param - dev - Pointer to the WLAN device.
6888 - skb - Pointer to OS packet (sk_buff).
6889 \return - success/fail
6890
6891 --------------------------------------------------------------------------*/
6892static void hdd_set_multicast_list(struct net_device *dev)
6893{
6894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 int mc_count;
6896 int i = 0;
6897 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306898
6899 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 {
6901 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306902 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 return;
6904 }
6905
6906 if (dev->flags & IFF_ALLMULTI)
6907 {
6908 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006909 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306910 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 }
6912 else
6913 {
6914 mc_count = netdev_mc_count(dev);
6915 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006916 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
6918 {
6919 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006920 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306921 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 return;
6923 }
6924
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306925 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07006926
6927 netdev_for_each_mc_addr(ha, dev) {
6928 if (i == mc_count)
6929 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306930 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
6931 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08006932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05306934 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 i++;
6936 }
6937 }
6938 return;
6939}
6940#endif
6941
6942/**---------------------------------------------------------------------------
6943
6944 \brief hdd_select_queue() -
6945
6946 This function is registered with the Linux OS for network
6947 core to decide which queue to use first.
6948
6949 \param - dev - Pointer to the WLAN device.
6950 - skb - Pointer to OS packet (sk_buff).
6951 \return - ac, Queue Index/access category corresponding to UP in IP header
6952
6953 --------------------------------------------------------------------------*/
6954v_U16_t hdd_select_queue(struct net_device *dev,
6955 struct sk_buff *skb)
6956{
6957 return hdd_wmm_select_queue(dev, skb);
6958}
6959
6960
6961/**---------------------------------------------------------------------------
6962
6963 \brief hdd_wlan_initial_scan() -
6964
6965 This function triggers the initial scan
6966
6967 \param - pAdapter - Pointer to the HDD adapter.
6968
6969 --------------------------------------------------------------------------*/
6970void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
6971{
6972 tCsrScanRequest scanReq;
6973 tCsrChannelInfo channelInfo;
6974 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07006975 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6977
6978 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
6979 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
6980 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
6981
6982 if(sme_Is11dSupported(pHddCtx->hHal))
6983 {
6984 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
6985 if ( HAL_STATUS_SUCCESS( halStatus ) )
6986 {
6987 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
6988 if( !scanReq.ChannelInfo.ChannelList )
6989 {
6990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
6991 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006992 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006993 return;
6994 }
6995 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
6996 channelInfo.numOfChannels);
6997 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
6998 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006999 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 }
7001
7002 scanReq.scanType = eSIR_PASSIVE_SCAN;
7003 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7004 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7005 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7006 }
7007 else
7008 {
7009 scanReq.scanType = eSIR_ACTIVE_SCAN;
7010 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7011 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7012 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7013 }
7014
7015 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7016 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7017 {
7018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7019 __func__, halStatus );
7020 }
7021
7022 if(sme_Is11dSupported(pHddCtx->hHal))
7023 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7024}
7025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026/**---------------------------------------------------------------------------
7027
7028 \brief hdd_full_power_callback() - HDD full power callback function
7029
7030 This is the function invoked by SME to inform the result of a full power
7031 request issued by HDD
7032
7033 \param - callbackcontext - Pointer to cookie
7034 \param - status - result of request
7035
7036 \return - None
7037
7038 --------------------------------------------------------------------------*/
7039static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7040{
Jeff Johnson72a40512013-12-19 10:14:15 -08007041 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007042
7043 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307044 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007045
7046 if (NULL == callbackContext)
7047 {
7048 hddLog(VOS_TRACE_LEVEL_ERROR,
7049 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007050 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 return;
7052 }
7053
Jeff Johnson72a40512013-12-19 10:14:15 -08007054 /* there is a race condition that exists between this callback
7055 function and the caller since the caller could time out either
7056 before or while this code is executing. we use a spinlock to
7057 serialize these actions */
7058 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007059
7060 if (POWER_CONTEXT_MAGIC != pContext->magic)
7061 {
7062 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007063 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 hddLog(VOS_TRACE_LEVEL_WARN,
7065 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007066 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 return;
7068 }
7069
Jeff Johnson72a40512013-12-19 10:14:15 -08007070 /* context is valid so caller is still waiting */
7071
7072 /* paranoia: invalidate the magic */
7073 pContext->magic = 0;
7074
7075 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007077
7078 /* serialization is complete */
7079 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007080}
7081
7082/**---------------------------------------------------------------------------
7083
7084 \brief hdd_wlan_exit() - HDD WLAN exit function
7085
7086 This is the driver exit point (invoked during rmmod)
7087
7088 \param - pHddCtx - Pointer to the HDD Context
7089
7090 \return - None
7091
7092 --------------------------------------------------------------------------*/
7093void hdd_wlan_exit(hdd_context_t *pHddCtx)
7094{
7095 eHalStatus halStatus;
7096 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7097 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307098 struct wiphy *wiphy = pHddCtx->wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 hdd_adapter_t* pAdapter;
Jeff Johnson72a40512013-12-19 10:14:15 -08007100 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 long lrc;
7102
7103 ENTER();
7104
Jeff Johnson88ba7742013-02-27 14:36:02 -08007105 if (VOS_FTM_MODE != hdd_get_conparam())
7106 {
7107 // Unloading, restart logic is no more required.
7108 wlan_hdd_restart_deinit(pHddCtx);
7109 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007110
Jeff Johnson295189b2012-06-20 16:38:30 -07007111 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 {
7115 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7116 WLAN_HDD_INFRA_STATION);
7117 if (pAdapter == NULL)
7118 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7119
7120 if (pAdapter != NULL)
7121 {
7122 wlan_hdd_cfg80211_pre_voss_stop(pAdapter);
7123 hdd_UnregisterWext(pAdapter->dev);
7124 }
7125 }
7126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007127
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007129 {
7130 wlan_hdd_ftm_close(pHddCtx);
7131 goto free_hdd_ctx;
7132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 //Stop the Interface TX queue.
7134 //netif_tx_disable(pWlanDev);
7135 //netif_carrier_off(pWlanDev);
7136
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7138 {
7139 pAdapter = hdd_get_adapter(pHddCtx,
7140 WLAN_HDD_SOFTAP);
7141 }
7142 else
7143 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 {
7146 pAdapter = hdd_get_adapter(pHddCtx,
7147 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007148 if (pAdapter == NULL)
7149 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 /* DeRegister with platform driver as client for Suspend/Resume */
7153 vosStatus = hddDeregisterPmOps(pHddCtx);
7154 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7155 {
7156 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7157 VOS_ASSERT(0);
7158 }
7159
7160 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7161 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7162 {
7163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007165
7166 // Cancel any outstanding scan requests. We are about to close all
7167 // of our adapters, but an adapter structure is what SME passes back
7168 // to our callback function. Hence if there are any outstanding scan
7169 // requests then there is a race condition between when the adapter
7170 // is closed and when the callback is invoked. We try to resolve that
7171 // race condition here by canceling any outstanding scans before we
7172 // close the adapters.
7173 // Note that the scans may be cancelled in an asynchronous manner, so
7174 // ideally there needs to be some kind of synchronization. Rather than
7175 // introduce a new synchronization here, we will utilize the fact that
7176 // we are about to Request Full Power, and since that is synchronized,
7177 // the expectation is that by the time Request Full Power has completed,
7178 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007179 if (NULL != pAdapter)
7180 hdd_abort_mac_scan( pHddCtx, pAdapter->sessionId);
7181 else
7182 hddLog(VOS_TRACE_LEVEL_ERROR,
7183 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007184
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007185 //Stop the traffic monitor timer
7186 if ( VOS_TIMER_STATE_RUNNING ==
7187 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7188 {
7189 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7190 }
7191
7192 // Destroy the traffic monitor timer
7193 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7194 &pHddCtx->tx_rx_trafficTmr)))
7195 {
7196 hddLog(VOS_TRACE_LEVEL_ERROR,
7197 "%s: Cannot deallocate Traffic monitor timer", __func__);
7198 }
7199
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 //Disable IMPS/BMPS as we do not want the device to enter any power
7201 //save mode during shutdown
7202 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7203 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7204 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7205
7206 //Ensure that device is in full power as we will touch H/W during vos_Stop
7207 init_completion(&powerContext.completion);
7208 powerContext.magic = POWER_CONTEXT_MAGIC;
7209
7210 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7211 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7212
7213 if (eHAL_STATUS_SUCCESS != halStatus)
7214 {
7215 if (eHAL_STATUS_PMC_PENDING == halStatus)
7216 {
7217 /* request was sent -- wait for the response */
7218 lrc = wait_for_completion_interruptible_timeout(
7219 &powerContext.completion,
7220 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 if (lrc <= 0)
7222 {
7223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007224 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 }
7226 }
7227 else
7228 {
7229 hddLog(VOS_TRACE_LEVEL_ERROR,
7230 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007231 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007232 /* continue -- need to clean up as much as possible */
7233 }
7234 }
7235
Jeff Johnson72a40512013-12-19 10:14:15 -08007236 /* either we never sent a request, we sent a request and received a
7237 response or we sent a request and timed out. if we never sent a
7238 request or if we sent a request and got a response, we want to
7239 clear the magic out of paranoia. if we timed out there is a
7240 race condition such that the callback function could be
7241 executing at the same time we are. of primary concern is if the
7242 callback function had already verified the "magic" but had not
7243 yet set the completion variable when a timeout occurred. we
7244 serialize these activities by invalidating the magic while
7245 holding a shared spinlock which will cause us to block if the
7246 callback is currently executing */
7247 spin_lock(&hdd_context_lock);
7248 powerContext.magic = 0;
7249 spin_unlock(&hdd_context_lock);
7250
Yue Ma0d4891e2013-08-06 17:01:45 -07007251 hdd_debugfs_exit(pHddCtx);
7252
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 // Unregister the Net Device Notifier
7254 unregister_netdevice_notifier(&hdd_netdev_notifier);
7255
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 hdd_stop_all_adapters( pHddCtx );
7257
Jeff Johnson295189b2012-06-20 16:38:30 -07007258#ifdef WLAN_BTAMP_FEATURE
7259 vosStatus = WLANBAP_Stop(pVosContext);
7260 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7261 {
7262 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7263 "%s: Failed to stop BAP",__func__);
7264 }
7265#endif //WLAN_BTAMP_FEATURE
7266
7267 //Stop all the modules
7268 vosStatus = vos_stop( pVosContext );
7269 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7270 {
7271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7272 "%s: Failed to stop VOSS",__func__);
7273 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7274 }
7275
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 //Assert Deep sleep signal now to put Libra HW in lowest power state
7277 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7278 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7279
7280 //Vote off any PMIC voltage supplies
7281 vos_chipPowerDown(NULL, NULL, NULL);
7282
7283 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7284
Leo Chang59cdc7e2013-07-10 10:08:21 -07007285
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007288
7289 //Close the scheduler before calling vos_close to make sure no thread is
7290 // scheduled after the each module close is called i.e after all the data
7291 // structures are freed.
7292 vosStatus = vos_sched_close( pVosContext );
7293 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7294 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7295 "%s: Failed to close VOSS Scheduler",__func__);
7296 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7297 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007298#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007299#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7300 /* Destroy the wake lock */
7301 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7302#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007303 /* Destroy the wake lock */
7304 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007305#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007306
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307307#ifdef CONFIG_ENABLE_LINUX_REG
7308 vosStatus = vos_nv_close();
7309 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7310 {
7311 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7312 "%s: Failed to close NV", __func__);
7313 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7314 }
7315#endif
7316
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 //Close VOSS
7318 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7319 vos_close(pVosContext);
7320
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 //Close Watchdog
7322 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7323 vos_watchdog_close(pVosContext);
7324
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307325 //Clean up HDD Nlink Service
7326 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007327#ifdef WLAN_KD_READY_NOTIFIER
7328 nl_srv_exit(pHddCtx->ptt_pid);
7329#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307330 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007331#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307332
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 /* Cancel the vote for XO Core ON.
7334 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7335 * exited at this point
7336 */
7337 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007338 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7340 {
7341 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7342 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007343 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 }
7345
7346 hdd_close_all_adapters( pHddCtx );
7347
7348
7349 //Free up dynamically allocated members inside HDD Adapter
7350 kfree(pHddCtx->cfg_ini);
7351 pHddCtx->cfg_ini= NULL;
7352
7353 /* free the power on lock from platform driver */
7354 if (free_riva_power_on_lock("wlan"))
7355 {
7356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7357 __func__);
7358 }
7359
Jeff Johnson88ba7742013-02-27 14:36:02 -08007360free_hdd_ctx:
Leo Changf04ddad2013-09-18 13:46:38 -07007361 /* FTM mode, WIPHY did not registered
7362 If un-register here, system crash will happen */
7363 if (VOS_FTM_MODE != hdd_get_conparam())
7364 {
7365 wiphy_unregister(wiphy) ;
7366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 if (hdd_is_ssr_required())
7369 {
7370 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007371 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 msleep(5000);
7373 }
7374 hdd_set_ssr_required (VOS_FALSE);
7375}
7376
7377
7378/**---------------------------------------------------------------------------
7379
7380 \brief hdd_update_config_from_nv() - Function to update the contents of
7381 the running configuration with parameters taken from NV storage
7382
7383 \param - pHddCtx - Pointer to the HDD global context
7384
7385 \return - VOS_STATUS_SUCCESS if successful
7386
7387 --------------------------------------------------------------------------*/
7388static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7389{
Jeff Johnson295189b2012-06-20 16:38:30 -07007390 v_BOOL_t itemIsValid = VOS_FALSE;
7391 VOS_STATUS status;
7392 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7393 v_U8_t macLoop;
7394
7395 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7396 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7397 if(status != VOS_STATUS_SUCCESS)
7398 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007399 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 return VOS_STATUS_E_FAILURE;
7401 }
7402
7403 if (itemIsValid == VOS_TRUE)
7404 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007405 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7407 VOS_MAX_CONCURRENCY_PERSONA);
7408 if(status != VOS_STATUS_SUCCESS)
7409 {
7410 /* Get MAC from NV fail, not update CFG info
7411 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007412 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 return VOS_STATUS_E_FAILURE;
7414 }
7415
7416 /* If first MAC is not valid, treat all others are not valid
7417 * Then all MACs will be got from ini file */
7418 if(vos_is_macaddr_zero(&macFromNV[0]))
7419 {
7420 /* MAC address in NV file is not configured yet */
7421 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7422 return VOS_STATUS_E_INVAL;
7423 }
7424
7425 /* Get MAC address from NV, update CFG info */
7426 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7427 {
7428 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7429 {
7430 printk(KERN_ERR "not valid MAC from NV for %d", macLoop);
7431 /* This MAC is not valid, skip it
7432 * This MAC will be got from ini file */
7433 }
7434 else
7435 {
7436 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7437 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7438 VOS_MAC_ADDR_SIZE);
7439 }
7440 }
7441 }
7442 else
7443 {
7444 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7445 return VOS_STATUS_E_FAILURE;
7446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448
7449 return VOS_STATUS_SUCCESS;
7450}
7451
7452/**---------------------------------------------------------------------------
7453
7454 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7455
7456 \param - pAdapter - Pointer to the HDD
7457
7458 \return - None
7459
7460 --------------------------------------------------------------------------*/
7461VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7462{
7463 eHalStatus halStatus;
7464 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307465 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007466
Jeff Johnson295189b2012-06-20 16:38:30 -07007467
7468 // Send ready indication to the HDD. This will kick off the MAC
7469 // into a 'running' state and should kick off an initial scan.
7470 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7471 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7472 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307473 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007474 "code %08d [x%08x]",__func__, halStatus, halStatus );
7475 return VOS_STATUS_E_FAILURE;
7476 }
7477
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307478 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7480 // And RIVA will crash
7481 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7482 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307483 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7484 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7485
7486
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 return VOS_STATUS_SUCCESS;
7488}
7489
Jeff Johnson295189b2012-06-20 16:38:30 -07007490/* wake lock APIs for HDD */
7491void hdd_prevent_suspend(void)
7492{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007493#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007495#else
7496 wcnss_prevent_suspend();
7497#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007498}
7499
7500void hdd_allow_suspend(void)
7501{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007502#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007504#else
7505 wcnss_allow_suspend();
7506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007507}
7508
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307509void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007510{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007511#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007512 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007513#else
7514 /* Do nothing as there is no API in wcnss for timeout*/
7515#endif
7516}
7517
Jeff Johnson295189b2012-06-20 16:38:30 -07007518/**---------------------------------------------------------------------------
7519
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007520 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7521 information between Host and Riva
7522
7523 This function gets reported version of FW
7524 It also finds the version of Riva headers used to compile the host
7525 It compares the above two and prints a warning if they are different
7526 It gets the SW and HW version string
7527 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7528 indicating the features they support through a bitmap
7529
7530 \param - pHddCtx - Pointer to HDD context
7531
7532 \return - void
7533
7534 --------------------------------------------------------------------------*/
7535
7536void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7537{
7538
7539 tSirVersionType versionCompiled;
7540 tSirVersionType versionReported;
7541 tSirVersionString versionString;
7542 tANI_U8 fwFeatCapsMsgSupported = 0;
7543 VOS_STATUS vstatus;
7544
7545 /* retrieve and display WCNSS version information */
7546 do {
7547
7548 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7549 &versionCompiled);
7550 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7551 {
7552 hddLog(VOS_TRACE_LEVEL_FATAL,
7553 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007554 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007555 break;
7556 }
7557
7558 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7559 &versionReported);
7560 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7561 {
7562 hddLog(VOS_TRACE_LEVEL_FATAL,
7563 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007564 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007565 break;
7566 }
7567
7568 if ((versionCompiled.major != versionReported.major) ||
7569 (versionCompiled.minor != versionReported.minor) ||
7570 (versionCompiled.version != versionReported.version) ||
7571 (versionCompiled.revision != versionReported.revision))
7572 {
7573 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
7574 "Host expected %u.%u.%u.%u\n",
7575 WLAN_MODULE_NAME,
7576 (int)versionReported.major,
7577 (int)versionReported.minor,
7578 (int)versionReported.version,
7579 (int)versionReported.revision,
7580 (int)versionCompiled.major,
7581 (int)versionCompiled.minor,
7582 (int)versionCompiled.version,
7583 (int)versionCompiled.revision);
7584 }
7585 else
7586 {
7587 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
7588 WLAN_MODULE_NAME,
7589 (int)versionReported.major,
7590 (int)versionReported.minor,
7591 (int)versionReported.version,
7592 (int)versionReported.revision);
7593 }
7594
7595 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
7596 versionString,
7597 sizeof(versionString));
7598 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7599 {
7600 hddLog(VOS_TRACE_LEVEL_FATAL,
7601 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007602 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007603 break;
7604 }
7605
7606 pr_info("%s: WCNSS software version %s\n",
7607 WLAN_MODULE_NAME, versionString);
7608
7609 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
7610 versionString,
7611 sizeof(versionString));
7612 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7613 {
7614 hddLog(VOS_TRACE_LEVEL_FATAL,
7615 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007616 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007617 break;
7618 }
7619
7620 pr_info("%s: WCNSS hardware version %s\n",
7621 WLAN_MODULE_NAME, versionString);
7622
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007623 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
7624 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007625 send the message only if it the riva is 1.1
7626 minor numbers for different riva branches:
7627 0 -> (1.0)Mainline Build
7628 1 -> (1.1)Mainline Build
7629 2->(1.04) Stability Build
7630 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007631 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007632 ((versionReported.minor>=1) && (versionReported.version>=1)))
7633 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
7634 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07007635
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007636 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08007637 {
7638#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
7639 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
7640 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
7641#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07007642 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
7643 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
7644 {
7645 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
7646 }
7647
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007648 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08007649 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007650
7651 } while (0);
7652
7653}
7654
7655/**---------------------------------------------------------------------------
7656
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307657 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
7658
7659 \param - pHddCtx - Pointer to the hdd context
7660
7661 \return - true if hardware supports 5GHz
7662
7663 --------------------------------------------------------------------------*/
7664static boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
7665{
7666 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
7667 * then hardware support 5Ghz.
7668 */
7669 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
7670 {
7671 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
7672 return true;
7673 }
7674 else
7675 {
7676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
7677 __func__);
7678 return false;
7679 }
7680}
7681
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307682/**---------------------------------------------------------------------------
7683
7684 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
7685 generate function
7686
7687 This is generate the random mac address for WLAN interface
7688
7689 \param - pHddCtx - Pointer to HDD context
7690 idx - Start interface index to get auto
7691 generated mac addr.
7692 mac_addr - Mac address
7693
7694 \return - 0 for success, < 0 for failure
7695
7696 --------------------------------------------------------------------------*/
7697
7698static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
7699 int idx, v_MACADDR_t mac_addr)
7700{
7701 int i;
7702 unsigned int serialno;
7703 serialno = wcnss_get_serial_number();
7704
7705 if (0 != serialno)
7706 {
7707 /* MAC address has 3 bytes of OUI so we have a maximum of 3
7708 bytes of the serial number that can be used to generate
7709 the other 3 bytes of the MAC address. Mask off all but
7710 the lower 3 bytes (this will also make sure we don't
7711 overflow in the next step) */
7712 serialno &= 0x00FFFFFF;
7713
7714 /* we need a unique address for each session */
7715 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
7716
7717 /* autogen other Mac addresses */
7718 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7719 {
7720 /* start with the entire default address */
7721 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
7722 /* then replace the lower 3 bytes */
7723 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
7724 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
7725 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
7726
7727 serialno++;
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 "%s: Derived Mac Addr: "
7730 MAC_ADDRESS_STR, __func__,
7731 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
7732 }
7733
7734 }
7735 else
7736 {
7737 hddLog(LOGE, FL("Failed to Get Serial NO"));
7738 return -1;
7739 }
7740 return 0;
7741}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307742
7743/**---------------------------------------------------------------------------
7744
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 \brief hdd_wlan_startup() - HDD init function
7746
7747 This is the driver startup code executed once a WLAN device has been detected
7748
7749 \param - dev - Pointer to the underlying device
7750
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007751 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07007752
7753 --------------------------------------------------------------------------*/
7754
7755int hdd_wlan_startup(struct device *dev )
7756{
7757 VOS_STATUS status;
7758 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07007759 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 hdd_context_t *pHddCtx = NULL;
7761 v_CONTEXT_t pVosContext= NULL;
7762#ifdef WLAN_BTAMP_FEATURE
7763 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
7764 WLANBAP_ConfigType btAmpConfig;
7765 hdd_config_t *pConfig;
7766#endif
7767 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05307769 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07007770
7771 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 /*
7773 * cfg80211: wiphy allocation
7774 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307775 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007776
7777 if(wiphy == NULL)
7778 {
7779 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007780 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 }
7782
7783 pHddCtx = wiphy_priv(wiphy);
7784
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 //Initialize the adapter context to zeros.
7786 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
7787
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 hdd_prevent_suspend();
7790 pHddCtx->isLoadUnloadInProgress = TRUE;
7791
7792 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
7793
7794 /*Get vos context here bcoz vos_open requires it*/
7795 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
7796
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08007797 if(pVosContext == NULL)
7798 {
7799 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
7800 goto err_free_hdd_context;
7801 }
7802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 //Save the Global VOSS context in adapter context for future.
7804 pHddCtx->pvosContext = pVosContext;
7805
7806 //Save the adapter context in global context for future.
7807 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
7808
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 pHddCtx->parent_dev = dev;
7810
7811 init_completion(&pHddCtx->full_pwr_comp_var);
7812 init_completion(&pHddCtx->standby_comp_var);
7813 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007814 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08007815 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307816 init_completion(&pHddCtx->wiphy_channel_update_event);
Amar Singhala49cbc52013-10-08 18:37:44 -07007817
7818#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07007819 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07007820#else
7821 init_completion(&pHddCtx->driver_crda_req);
7822#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007823
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05307824 spin_lock_init(&pHddCtx->schedScan_lock);
7825
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
7827
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307828#ifdef FEATURE_WLAN_TDLS
7829 /* tdls_lock is initialized before an hdd_open_adapter ( which is
7830 * invoked by other instances also) to protect the concurrent
7831 * access for the Adapters by TDLS module.
7832 */
7833 mutex_init(&pHddCtx->tdls_lock);
7834#endif
7835
Kiet Lam46b8e4e2013-11-06 21:49:53 +05307836 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 // Load all config first as TL config is needed during vos_open
7838 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
7839 if(pHddCtx->cfg_ini == NULL)
7840 {
7841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
7842 goto err_free_hdd_context;
7843 }
7844
7845 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
7846
7847 // Read and parse the qcom_cfg.ini file
7848 status = hdd_parse_config_ini( pHddCtx );
7849 if ( VOS_STATUS_SUCCESS != status )
7850 {
7851 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
7852 __func__, WLAN_INI_FILE);
7853 goto err_config;
7854 }
Arif Hussaind5218912013-12-05 01:10:55 -08007855#ifdef MEMORY_DEBUG
7856 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
7857 vos_mem_init();
7858
7859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
7860 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
7861#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007862
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05307863 /* INI has been read, initialise the configuredMcastBcastFilter with
7864 * INI value as this will serve as the default value
7865 */
7866 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
7867 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
7868 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05307869
7870 if (false == hdd_is_5g_supported(pHddCtx))
7871 {
7872 //5Ghz is not supported.
7873 if (1 != pHddCtx->cfg_ini->nBandCapability)
7874 {
7875 hddLog(VOS_TRACE_LEVEL_INFO,
7876 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
7877 pHddCtx->cfg_ini->nBandCapability = 1;
7878 }
7879 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05307880
7881 /* If SNR Monitoring is enabled, FW has to parse all beacons
7882 * for calcaluting and storing the average SNR, so set Nth beacon
7883 * filter to 1 to enable FW to parse all the beaocons
7884 */
7885 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
7886 {
7887 /* The log level is deliberately set to WARN as overriding
7888 * nthBeaconFilter to 1 will increase power cosumption and this
7889 * might just prove helpful to detect the power issue.
7890 */
7891 hddLog(VOS_TRACE_LEVEL_WARN,
7892 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
7893 pHddCtx->cfg_ini->nthBeaconFilter = 1;
7894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007895 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307896 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08007898 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08007900 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
7901 {
7902 hddLog(VOS_TRACE_LEVEL_FATAL,
7903 "%s: wlan_hdd_cfg80211_init return failure", __func__);
7904 goto err_config;
7905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007907
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007908 // Update VOS trace levels based upon the cfg.ini
7909 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
7910 pHddCtx->cfg_ini->vosTraceEnableBAP);
7911 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
7912 pHddCtx->cfg_ini->vosTraceEnableTL);
7913 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
7914 pHddCtx->cfg_ini->vosTraceEnableWDI);
7915 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
7916 pHddCtx->cfg_ini->vosTraceEnableHDD);
7917 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
7918 pHddCtx->cfg_ini->vosTraceEnableSME);
7919 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
7920 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05307921 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
7922 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007923 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
7924 pHddCtx->cfg_ini->vosTraceEnableWDA);
7925 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
7926 pHddCtx->cfg_ini->vosTraceEnableSYS);
7927 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
7928 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007929 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
7930 pHddCtx->cfg_ini->vosTraceEnableSAP);
7931 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
7932 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08007933
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 // Update WDI trace levels based upon the cfg.ini
7935 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
7936 pHddCtx->cfg_ini->wdiTraceEnableDAL);
7937 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
7938 pHddCtx->cfg_ini->wdiTraceEnableCTL);
7939 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
7940 pHddCtx->cfg_ini->wdiTraceEnableDAT);
7941 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
7942 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007943
Jeff Johnson88ba7742013-02-27 14:36:02 -08007944 if (VOS_FTM_MODE == hdd_get_conparam())
7945 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
7947 {
7948 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
7949 goto err_free_hdd_context;
7950 }
7951 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
7952 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08007953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007954
Jeff Johnson88ba7742013-02-27 14:36:02 -08007955 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7957 {
7958 status = vos_watchdog_open(pVosContext,
7959 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
7960
7961 if(!VOS_IS_STATUS_SUCCESS( status ))
7962 {
7963 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307964 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 }
7966 }
7967
7968 pHddCtx->isLogpInProgress = FALSE;
7969 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
7970
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
7972 if(!VOS_IS_STATUS_SUCCESS(status))
7973 {
7974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 }
7977
Amar Singhala49cbc52013-10-08 18:37:44 -07007978#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007979 /* initialize the NV module. This is required so that
7980 we can initialize the channel information in wiphy
7981 from the NV.bin data. The channel information in
7982 wiphy needs to be initialized before wiphy registration */
7983
7984 status = vos_nv_open();
7985 if (!VOS_IS_STATUS_SUCCESS(status))
7986 {
7987 /* NV module cannot be initialized */
7988 hddLog( VOS_TRACE_LEVEL_FATAL,
7989 "%s: vos_nv_open failed", __func__);
7990 goto err_clkvote;
7991 }
7992
7993 status = vos_init_wiphy_from_nv_bin();
7994 if (!VOS_IS_STATUS_SUCCESS(status))
7995 {
7996 /* NV module cannot be initialized */
7997 hddLog( VOS_TRACE_LEVEL_FATAL,
7998 "%s: vos_init_wiphy failed", __func__);
7999 goto err_vos_nv_close;
8000 }
8001
Amar Singhala49cbc52013-10-08 18:37:44 -07008002 /* registration of wiphy dev with cfg80211 */
8003 if (0 > wlan_hdd_cfg80211_register(wiphy))
8004 {
8005 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
Amar Singhal0a402232013-10-11 20:57:16 -07008006 goto err_vos_nv_close;
Amar Singhala49cbc52013-10-08 18:37:44 -07008007 }
8008#endif
8009
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 status = vos_open( &pVosContext, 0);
8011 if ( !VOS_IS_STATUS_SUCCESS( status ))
8012 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Amar Singhala49cbc52013-10-08 18:37:44 -07008014 goto err_wiphy_unregister;
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 }
8016
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8018
8019 if ( NULL == pHddCtx->hHal )
8020 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008021 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 goto err_vosclose;
8023 }
8024
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008025 status = vos_preStart( pHddCtx->pvosContext );
8026 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8027 {
8028 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
8029 goto err_vosclose;
8030 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008031
Arif Hussaineaf68602013-12-30 23:10:44 -08008032 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8033 {
8034 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8036 __func__, enable_dfs_chan_scan);
8037 }
8038 if (0 == enable_11d || 1 == enable_11d)
8039 {
8040 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8042 __func__, enable_11d);
8043 }
8044
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008045 /* Note that the vos_preStart() sequence triggers the cfg download.
8046 The cfg download must occur before we update the SME config
8047 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 status = hdd_set_sme_config( pHddCtx );
8049
8050 if ( VOS_STATUS_SUCCESS != status )
8051 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008052 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
8053 goto err_vosclose;
8054 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008055
8056 //Initialize the WMM module
8057 status = hdd_wmm_init(pHddCtx);
8058 if (!VOS_IS_STATUS_SUCCESS(status))
8059 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008060 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 goto err_vosclose;
8062 }
8063
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 /* In the integrated architecture we update the configuration from
8065 the INI file and from NV before vOSS has been started so that
8066 the final contents are available to send down to the cCPU */
8067
8068 // Apply the cfg.ini to cfg.dat
8069 if (FALSE == hdd_update_config_dat(pHddCtx))
8070 {
8071 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
8072 goto err_vosclose;
8073 }
8074
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308075 // Get mac addr from platform driver
8076 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8077
8078 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308080 /* Store the mac addr for first interface */
8081 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8082
8083 hddLog(VOS_TRACE_LEVEL_ERROR,
8084 "%s: WLAN Mac Addr: "
8085 MAC_ADDRESS_STR, __func__,
8086 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8087
8088 /* Here, passing Arg2 as 1 because we do not want to change the
8089 last 3 bytes (means non OUI bytes) of first interface mac
8090 addr.
8091 */
8092 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8093 {
8094 hddLog(VOS_TRACE_LEVEL_ERROR,
8095 "%s: Failed to generate wlan interface mac addr "
8096 "using MAC from ini file ", __func__);
8097 }
8098 }
8099 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8100 {
8101 // Apply the NV to cfg.dat
8102 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008103#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8104 /* There was not a valid set of MAC Addresses in NV. See if the
8105 default addresses were modified by the cfg.ini settings. If so,
8106 we'll use them, but if not, we'll autogenerate a set of MAC
8107 addresses based upon the device serial number */
8108
8109 static const v_MACADDR_t default_address =
8110 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008111
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308112 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8113 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 {
8115 /* cfg.ini has the default address, invoke autogen logic */
8116
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308117 /* Here, passing Arg2 as 0 because we want to change the
8118 last 3 bytes (means non OUI bytes) of all the interfaces
8119 mac addr.
8120 */
8121 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8122 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308124 hddLog(VOS_TRACE_LEVEL_ERROR,
8125 "%s: Failed to generate wlan interface mac addr "
8126 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8127 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 }
8130 else
8131#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8132 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008133 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 "%s: Invalid MAC address in NV, using MAC from ini file "
8135 MAC_ADDRESS_STR, __func__,
8136 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8137 }
8138 }
8139 {
8140 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308141
8142 /* Set the MAC Address Currently this is used by HAL to
8143 * add self sta. Remove this once self sta is added as
8144 * part of session open.
8145 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8147 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8148 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308149
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 if (!HAL_STATUS_SUCCESS( halStatus ))
8151 {
8152 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8153 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Madan Mohan Koyyalamudib8b126b2012-11-15 17:37:30 -08008154 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 }
8156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008157
8158 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8159 Note: Firmware image will be read and downloaded inside vos_start API */
8160 status = vos_start( pHddCtx->pvosContext );
8161 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8162 {
8163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
8164 goto err_vosclose;
8165 }
8166
Leo Chang6cec3e22014-01-21 15:33:49 -08008167#ifdef FEATURE_WLAN_CH_AVOID
8168 /* Plug in avoid channel notification callback
8169 * This should happen before ADD_SELF_STA
8170 * FW will send first IND with ADD_SELF_STA REQ from host */
8171 sme_AddChAvoidCallback(pHddCtx->hHal,
8172 hdd_hostapd_ch_avoid_cb);
8173#endif /* FEATURE_WLAN_CH_AVOID */
8174
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008175 /* Exchange capability info between Host and FW and also get versioning info from FW */
8176 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008177
8178 status = hdd_post_voss_start_config( pHddCtx );
8179 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8180 {
8181 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8182 __func__);
8183 goto err_vosstop;
8184 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008185
8186#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308187 wlan_hdd_cfg80211_update_reg_info( wiphy );
8188
8189 /* registration of wiphy dev with cfg80211 */
8190 if (0 > wlan_hdd_cfg80211_register(wiphy))
8191 {
8192 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8193 goto err_vosstop;
8194 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008195#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008196
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8198 {
8199 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8200 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8201 }
8202 else
8203 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8205 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8206 if (pAdapter != NULL)
8207 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308208 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308210 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8211 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8212 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008213
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308214 /* Generate the P2P Device Address. This consists of the device's
8215 * primary MAC address with the locally administered bit set.
8216 */
8217 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008218 }
8219 else
8220 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308221 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8222 if (p2p_dev_addr != NULL)
8223 {
8224 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8225 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8226 }
8227 else
8228 {
8229 hddLog(VOS_TRACE_LEVEL_FATAL,
8230 "%s: Failed to allocate mac_address for p2p_device",
8231 __func__);
8232 goto err_close_adapter;
8233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008235
8236 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8237 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8238 if ( NULL == pP2pAdapter )
8239 {
8240 hddLog(VOS_TRACE_LEVEL_FATAL,
8241 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008242 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008243 goto err_close_adapter;
8244 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008247
8248 if( pAdapter == NULL )
8249 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8251 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008253
Arif Hussain66559122013-11-21 10:11:40 -08008254 if (country_code)
8255 {
8256 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008257 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008258 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8259#ifndef CONFIG_ENABLE_LINUX_REG
8260 hdd_checkandupdate_phymode(pAdapter, country_code);
8261#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008262 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8263 (void *)(tSmeChangeCountryCallback)
8264 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008265 country_code,
8266 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308267 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008268 if (eHAL_STATUS_SUCCESS == ret)
8269 {
Arif Hussaincb607082013-12-20 11:57:42 -08008270 ret = wait_for_completion_interruptible_timeout(
8271 &pAdapter->change_country_code,
8272 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8273
8274 if (0 >= ret)
8275 {
8276 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8277 "%s: SME while setting country code timed out", __func__);
8278 }
Arif Hussain66559122013-11-21 10:11:40 -08008279 }
8280 else
8281 {
Arif Hussaincb607082013-12-20 11:57:42 -08008282 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8283 "%s: SME Change Country code from module param fail ret=%d",
8284 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008285 }
8286 }
8287
Jeff Johnson295189b2012-06-20 16:38:30 -07008288#ifdef WLAN_BTAMP_FEATURE
8289 vStatus = WLANBAP_Open(pVosContext);
8290 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8291 {
8292 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8293 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008294 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 }
8296
8297 vStatus = BSL_Init(pVosContext);
8298 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8299 {
8300 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8301 "%s: Failed to Init BSL",__func__);
8302 goto err_bap_close;
8303 }
8304 vStatus = WLANBAP_Start(pVosContext);
8305 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8306 {
8307 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8308 "%s: Failed to start TL",__func__);
8309 goto err_bap_close;
8310 }
8311
8312 pConfig = pHddCtx->cfg_ini;
8313 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8314 status = WLANBAP_SetConfig(&btAmpConfig);
8315
8316#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008317
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008318#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8319 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8320 {
8321 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8322 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8323 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8324 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8325 }
8326#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008327#ifdef FEATURE_WLAN_SCAN_PNO
8328 /*SME must send channel update configuration to RIVA*/
8329 sme_UpdateChannelConfig(pHddCtx->hHal);
8330#endif
8331
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 /* Register with platform driver as client for Suspend/Resume */
8333 status = hddRegisterPmOps(pHddCtx);
8334 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8335 {
8336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8337#ifdef WLAN_BTAMP_FEATURE
8338 goto err_bap_stop;
8339#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008340 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008341#endif //WLAN_BTAMP_FEATURE
8342 }
8343
Yue Ma0d4891e2013-08-06 17:01:45 -07008344 /* Open debugfs interface */
8345 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8346 {
8347 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8348 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008349 }
8350
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 /* Register TM level change handler function to the platform */
8352 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8353 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8354 {
8355 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8356 goto err_unregister_pmops;
8357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008358
8359 /* register for riva power on lock to platform driver */
8360 if (req_riva_power_on_lock("wlan"))
8361 {
8362 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8363 __func__);
8364 goto err_unregister_pmops;
8365 }
8366
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 // register net device notifier for device change notification
8368 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8369
8370 if(ret < 0)
8371 {
8372 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8373 goto err_free_power_on_lock;
8374 }
8375
8376 //Initialize the nlink service
8377 if(nl_srv_init() != 0)
8378 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308379 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 goto err_reg_netdev;
8381 }
8382
Leo Chang4ce1cc52013-10-21 18:27:15 -07008383#ifdef WLAN_KD_READY_NOTIFIER
8384 pHddCtx->kd_nl_init = 1;
8385#endif /* WLAN_KD_READY_NOTIFIER */
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 //Initialize the BTC service
8388 if(btc_activate_service(pHddCtx) != 0)
8389 {
8390 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8391 goto err_nl_srv;
8392 }
8393
8394#ifdef PTT_SOCK_SVC_ENABLE
8395 //Initialize the PTT service
8396 if(ptt_sock_activate_svc(pHddCtx) != 0)
8397 {
8398 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8399 goto err_nl_srv;
8400 }
8401#endif
8402
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008406 /* Action frame registered in one adapter which will
8407 * applicable to all interfaces
8408 */
Madan Mohan Koyyalamudie233e292012-09-18 17:38:02 -07008409 wlan_hdd_cfg80211_post_voss_start(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008411
8412 mutex_init(&pHddCtx->sap_lock);
8413
8414 pHddCtx->isLoadUnloadInProgress = FALSE;
8415
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008416#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008417#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8418 /* Initialize the wake lcok */
8419 wake_lock_init(&pHddCtx->rx_wake_lock,
8420 WAKE_LOCK_SUSPEND,
8421 "qcom_rx_wakelock");
8422#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008423 /* Initialize the wake lcok */
8424 wake_lock_init(&pHddCtx->sap_wake_lock,
8425 WAKE_LOCK_SUSPEND,
8426 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008427#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008428
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008429 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8430 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008431
8432 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8433 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308434#ifndef CONFIG_ENABLE_LINUX_REG
8435 /*updating wiphy so that regulatory user hints can be processed*/
8436 if (wiphy)
8437 {
8438 regulatory_hint(wiphy, "00");
8439 }
8440#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008441 // Initialize the restart logic
8442 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308443
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008444 //Register the traffic monitor timer now
8445 if ( pHddCtx->cfg_ini->dynSplitscan)
8446 {
8447 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8448 VOS_TIMER_TYPE_SW,
8449 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8450 (void *)pHddCtx);
8451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 goto success;
8453
8454err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008455#ifdef WLAN_KD_READY_NOTIFIER
8456 nl_srv_exit(pHddCtx->ptt_pid);
8457#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008459#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008460err_reg_netdev:
8461 unregister_netdevice_notifier(&hdd_netdev_notifier);
8462
8463err_free_power_on_lock:
8464 free_riva_power_on_lock("wlan");
8465
8466err_unregister_pmops:
8467 hddDevTmUnregisterNotifyCallback(pHddCtx);
8468 hddDeregisterPmOps(pHddCtx);
8469
Yue Ma0d4891e2013-08-06 17:01:45 -07008470 hdd_debugfs_exit(pHddCtx);
8471
Jeff Johnson295189b2012-06-20 16:38:30 -07008472#ifdef WLAN_BTAMP_FEATURE
8473err_bap_stop:
8474 WLANBAP_Stop(pVosContext);
8475#endif
8476
8477#ifdef WLAN_BTAMP_FEATURE
8478err_bap_close:
8479 WLANBAP_Close(pVosContext);
8480#endif
8481
Jeff Johnson295189b2012-06-20 16:38:30 -07008482err_close_adapter:
8483 hdd_close_all_adapters( pHddCtx );
Amar Singhala49cbc52013-10-08 18:37:44 -07008484
8485#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308486 wiphy_unregister(wiphy) ;
Amar Singhala49cbc52013-10-08 18:37:44 -07008487#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008488
8489err_vosstop:
8490 vos_stop(pVosContext);
8491
Amar Singhala49cbc52013-10-08 18:37:44 -07008492err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 status = vos_sched_close( pVosContext );
8494 if (!VOS_IS_STATUS_SUCCESS(status)) {
8495 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8496 "%s: Failed to close VOSS Scheduler", __func__);
8497 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8498 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008499 vos_close(pVosContext );
8500
8501err_wiphy_unregister:
8502
8503#ifdef CONFIG_ENABLE_LINUX_REG
8504 wiphy_unregister(wiphy);
Jeff Johnson295189b2012-06-20 16:38:30 -07008505
Amar Singhal0a402232013-10-11 20:57:16 -07008506err_vos_nv_close:
8507
8508 vos_nv_close();
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510err_clkvote:
Amar Singhala49cbc52013-10-08 18:37:44 -07008511#endif
8512
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008513 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008514
8515err_wdclose:
8516 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8517 vos_watchdog_close(pVosContext);
8518
Jeff Johnson295189b2012-06-20 16:38:30 -07008519err_config:
8520 kfree(pHddCtx->cfg_ini);
8521 pHddCtx->cfg_ini= NULL;
8522
8523err_free_hdd_context:
8524 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 wiphy_free(wiphy) ;
8526 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 VOS_BUG(1);
8528
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08008529 if (hdd_is_ssr_required())
8530 {
8531 /* WDI timeout had happened during load, so SSR is needed here */
8532 subsystem_restart("wcnss");
8533 msleep(5000);
8534 }
8535 hdd_set_ssr_required (VOS_FALSE);
8536
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008537 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008538
8539success:
8540 EXIT();
8541 return 0;
8542}
8543
8544/**---------------------------------------------------------------------------
8545
Jeff Johnson32d95a32012-09-10 13:15:23 -07008546 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07008547
Jeff Johnson32d95a32012-09-10 13:15:23 -07008548 This is the driver entry point - called in different timeline depending
8549 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07008550
8551 \param - None
8552
8553 \return - 0 for success, non zero for failure
8554
8555 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07008556static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008557{
8558 VOS_STATUS status;
8559 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 struct device *dev = NULL;
8561 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008562#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8563 int max_retries = 0;
8564#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008565
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308566#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8567 vos_wconn_trace_init();
8568#endif
8569
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 ENTER();
8571
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008572#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07008574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008575
8576 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
8577 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
8578
8579 //Power Up Libra WLAN card first if not already powered up
8580 status = vos_chipPowerUp(NULL,NULL,NULL);
8581 if (!VOS_IS_STATUS_SUCCESS(status))
8582 {
8583 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
8584 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308585#ifdef WLAN_OPEN_SOURCE
8586 wake_lock_destroy(&wlan_wake_lock);
8587#endif
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008588 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 }
8590
Jeff Johnson295189b2012-06-20 16:38:30 -07008591#ifdef ANI_BUS_TYPE_PCI
8592
8593 dev = wcnss_wlan_get_device();
8594
8595#endif // ANI_BUS_TYPE_PCI
8596
8597#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008598
8599#ifdef HAVE_WCNSS_CAL_DOWNLOAD
8600 /* wait until WCNSS driver downloads NV */
8601 while (!wcnss_device_ready() && 5 >= ++max_retries) {
8602 msleep(1000);
8603 }
8604 if (max_retries >= 5) {
8605 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05308606#ifdef WLAN_OPEN_SOURCE
8607 wake_lock_destroy(&wlan_wake_lock);
8608#endif
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07008609 return -ENODEV;
8610 }
8611#endif
8612
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 dev = wcnss_wlan_get_device();
8614#endif // ANI_BUS_TYPE_PLATFORM
8615
8616
8617 do {
8618 if (NULL == dev) {
8619 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
8620 ret_status = -1;
8621 break;
8622 }
8623
Jeff Johnson295189b2012-06-20 16:38:30 -07008624#ifdef TIMER_MANAGER
8625 vos_timer_manager_init();
8626#endif
8627
8628 /* Preopen VOSS so that it is ready to start at least SAL */
8629 status = vos_preOpen(&pVosContext);
8630
8631 if (!VOS_IS_STATUS_SUCCESS(status))
8632 {
8633 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
8634 ret_status = -1;
8635 break;
8636 }
8637
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008638#ifndef MODULE
8639 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
8640 */
8641 hdd_set_conparam((v_UINT_t)con_mode);
8642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008643
8644 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008645 if (hdd_wlan_startup(dev))
8646 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008648 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 vos_preClose( &pVosContext );
8650 ret_status = -1;
8651 break;
8652 }
8653
8654 /* Cancel the vote for XO Core ON
8655 * This is done here for safety purposes in case we re-initialize without turning
8656 * it OFF in any error scenario.
8657 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008658 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07008660 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
8662 {
8663 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08008664 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07008665 }
8666 } while (0);
8667
8668 if (0 != ret_status)
8669 {
8670 //Assert Deep sleep signal now to put Libra HW in lowest power state
8671 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
8672 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
8673
8674 //Vote off any PMIC voltage supplies
8675 vos_chipPowerDown(NULL, NULL, NULL);
8676#ifdef TIMER_MANAGER
8677 vos_timer_exit();
8678#endif
8679#ifdef MEMORY_DEBUG
8680 vos_mem_exit();
8681#endif
8682
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008683#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008685#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
8687 }
8688 else
8689 {
8690 //Send WLAN UP indication to Nlink Service
8691 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
8692
8693 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 }
8695
8696 EXIT();
8697
8698 return ret_status;
8699}
8700
Jeff Johnson32d95a32012-09-10 13:15:23 -07008701/**---------------------------------------------------------------------------
8702
8703 \brief hdd_module_init() - Init Function
8704
8705 This is the driver entry point (invoked when module is loaded using insmod)
8706
8707 \param - None
8708
8709 \return - 0 for success, non zero for failure
8710
8711 --------------------------------------------------------------------------*/
8712#ifdef MODULE
8713static int __init hdd_module_init ( void)
8714{
8715 return hdd_driver_init();
8716}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008717#else /* #ifdef MODULE */
8718static int __init hdd_module_init ( void)
8719{
8720 /* Driver initialization is delayed to fwpath_changed_handler */
8721 return 0;
8722}
Jeff Johnson32d95a32012-09-10 13:15:23 -07008723#endif /* #ifdef MODULE */
8724
Jeff Johnson295189b2012-06-20 16:38:30 -07008725
8726/**---------------------------------------------------------------------------
8727
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008728 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008729
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008730 This is the driver exit point (invoked when module is unloaded using rmmod
8731 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07008732
8733 \param - None
8734
8735 \return - None
8736
8737 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008738static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07008739{
8740 hdd_context_t *pHddCtx = NULL;
8741 v_CONTEXT_t pVosContext = NULL;
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008742 int retry = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008743
8744 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
8745
8746 //Get the global vos context
8747 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8748
8749 if(!pVosContext)
8750 {
8751 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
8752 goto done;
8753 }
8754
8755 //Get the HDD context.
8756 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
8757
8758 if(!pHddCtx)
8759 {
8760 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
8761 }
8762 else
8763 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008764 while(isWDresetInProgress()) {
8765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8766 "%s:SSR in Progress; block rmmod for 1 second!!!", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008767 msleep(1000);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07008768
8769 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
8770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8771 "%s:SSR never completed, fatal error", __func__);
8772 VOS_BUG(0);
8773 }
8774 }
8775
Jeff Johnson295189b2012-06-20 16:38:30 -07008776
8777 pHddCtx->isLoadUnloadInProgress = TRUE;
8778 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8779
8780 //Do all the cleanup before deregistering the driver
8781 hdd_wlan_exit(pHddCtx);
8782 }
8783
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 vos_preClose( &pVosContext );
8785
8786#ifdef TIMER_MANAGER
8787 vos_timer_exit();
8788#endif
8789#ifdef MEMORY_DEBUG
8790 vos_mem_exit();
8791#endif
8792
Gopichand Nakkalad0774962013-05-24 11:32:21 +05308793#ifdef WCONN_TRACE_KMSG_LOG_BUFF
8794 vos_wconn_trace_exit();
8795#endif
8796
Jeff Johnson295189b2012-06-20 16:38:30 -07008797done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008798#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
8802}
8803
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008804/**---------------------------------------------------------------------------
8805
8806 \brief hdd_module_exit() - Exit function
8807
8808 This is the driver exit point (invoked when module is unloaded using rmmod)
8809
8810 \param - None
8811
8812 \return - None
8813
8814 --------------------------------------------------------------------------*/
8815static void __exit hdd_module_exit(void)
8816{
8817 hdd_driver_exit();
8818}
8819
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008820#ifdef MODULE
8821static int fwpath_changed_handler(const char *kmessage,
8822 struct kernel_param *kp)
8823{
Jeff Johnson76052702013-04-16 13:55:05 -07008824 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008825}
8826
8827static int con_mode_handler(const char *kmessage,
8828 struct kernel_param *kp)
8829{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07008830 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008831}
8832#else /* #ifdef MODULE */
8833/**---------------------------------------------------------------------------
8834
Jeff Johnson76052702013-04-16 13:55:05 -07008835 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008836
Jeff Johnson76052702013-04-16 13:55:05 -07008837 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008838 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07008839 - invoked when module parameter fwpath is modified from userspace to signal
8840 initializing the WLAN driver or when con_mode is modified from userspace
8841 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008842
8843 \return - 0 for success, non zero for failure
8844
8845 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008846static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008847{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008848 int ret_status;
8849
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008850 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008851 ret_status = hdd_driver_init();
8852 wlan_hdd_inited = ret_status ? 0 : 1;
8853 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008854 }
8855
8856 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07008857
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008858 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07008859
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07008860 ret_status = hdd_driver_init();
8861 wlan_hdd_inited = ret_status ? 0 : 1;
8862 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07008863}
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865/**---------------------------------------------------------------------------
8866
Jeff Johnson76052702013-04-16 13:55:05 -07008867 \brief fwpath_changed_handler() - Handler Function
8868
8869 Handle changes to the fwpath parameter
8870
8871 \return - 0 for success, non zero for failure
8872
8873 --------------------------------------------------------------------------*/
8874static int fwpath_changed_handler(const char *kmessage,
8875 struct kernel_param *kp)
8876{
8877 int ret;
8878
8879 ret = param_set_copystring(kmessage, kp);
8880 if (0 == ret)
8881 ret = kickstart_driver();
8882 return ret;
8883}
8884
8885/**---------------------------------------------------------------------------
8886
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008887 \brief con_mode_handler() -
8888
8889 Handler function for module param con_mode when it is changed by userspace
8890 Dynamically linked - do nothing
8891 Statically linked - exit and init driver, as in rmmod and insmod
8892
Jeff Johnson76052702013-04-16 13:55:05 -07008893 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008894
Jeff Johnson76052702013-04-16 13:55:05 -07008895 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008896
8897 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07008898static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008899{
Jeff Johnson76052702013-04-16 13:55:05 -07008900 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008901
Jeff Johnson76052702013-04-16 13:55:05 -07008902 ret = param_set_int(kmessage, kp);
8903 if (0 == ret)
8904 ret = kickstart_driver();
8905 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008906}
8907#endif /* #ifdef MODULE */
8908
8909/**---------------------------------------------------------------------------
8910
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 \brief hdd_get_conparam() -
8912
8913 This is the driver exit point (invoked when module is unloaded using rmmod)
8914
8915 \param - None
8916
8917 \return - tVOS_CON_MODE
8918
8919 --------------------------------------------------------------------------*/
8920tVOS_CON_MODE hdd_get_conparam ( void )
8921{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008922#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008924#else
8925 return (tVOS_CON_MODE)curr_con_mode;
8926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008927}
8928void hdd_set_conparam ( v_UINT_t newParam )
8929{
8930 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07008931#ifndef MODULE
8932 curr_con_mode = con_mode;
8933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008934}
8935/**---------------------------------------------------------------------------
8936
8937 \brief hdd_softap_sta_deauth() - function
8938
8939 This to take counter measure to handle deauth req from HDD
8940
8941 \param - pAdapter - Pointer to the HDD
8942
8943 \param - enable - boolean value
8944
8945 \return - None
8946
8947 --------------------------------------------------------------------------*/
8948
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008949VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008950{
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008952 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
8954 ENTER();
8955
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008956 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
8957 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008958
8959 //Ignore request to deauth bcmc station
8960 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008961 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008962
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008963 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07008964
8965 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008966 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07008967}
8968
8969/**---------------------------------------------------------------------------
8970
8971 \brief hdd_softap_sta_disassoc() - function
8972
8973 This to take counter measure to handle deauth req from HDD
8974
8975 \param - pAdapter - Pointer to the HDD
8976
8977 \param - enable - boolean value
8978
8979 \return - None
8980
8981 --------------------------------------------------------------------------*/
8982
8983void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
8984{
8985 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
8986
8987 ENTER();
8988
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308989 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008990
8991 //Ignore request to disassoc bcmc station
8992 if( pDestMacAddress[0] & 0x1 )
8993 return;
8994
8995 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
8996}
8997
8998void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
8999{
9000 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9001
9002 ENTER();
9003
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309004 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009005
9006 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9007}
9008
Jeff Johnson295189b2012-06-20 16:38:30 -07009009/**---------------------------------------------------------------------------
9010 *
9011 * \brief hdd_get__concurrency_mode() -
9012 *
9013 *
9014 * \param - None
9015 *
9016 * \return - CONCURRENCY MODE
9017 *
9018 * --------------------------------------------------------------------------*/
9019tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9020{
9021 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9022 hdd_context_t *pHddCtx;
9023
9024 if (NULL != pVosContext)
9025 {
9026 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9027 if (NULL != pHddCtx)
9028 {
9029 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9030 }
9031 }
9032
9033 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009034 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 return VOS_STA;
9036}
9037
9038/* Decide whether to allow/not the apps power collapse.
9039 * Allow apps power collapse if we are in connected state.
9040 * if not, allow only if we are in IMPS */
9041v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9042{
9043 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009044 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009045 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009046 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9047 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9048 hdd_adapter_t *pAdapter = NULL;
9049 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009050 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9053 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009054
Yathish9f22e662012-12-10 14:21:35 -08009055 concurrent_state = hdd_get_concurrency_mode();
9056
9057#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9058 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9059 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9060 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9061 return TRUE;
9062#endif
9063
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 /*loop through all adapters. TBD fix for Concurrency */
9065 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9066 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9067 {
9068 pAdapter = pAdapterNode->pAdapter;
9069 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9070 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9071 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009072 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 && (pmcState != IMPS && pmcState != BMPS
Srikant Kuppafef66a72013-01-30 17:32:44 -08009074 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009075 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9076 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009078 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009079 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9080 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 return FALSE;
9082 }
9083 }
9084 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9085 pAdapterNode = pNext;
9086 }
9087 return TRUE;
9088}
9089
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009090/* Decides whether to send suspend notification to Riva
9091 * if any adapter is in BMPS; then it is required */
9092v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9093{
9094 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9095 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9096
9097 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9098 {
9099 return TRUE;
9100 }
9101 return FALSE;
9102}
9103
Jeff Johnson295189b2012-06-20 16:38:30 -07009104void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9105{
9106 switch(mode)
9107 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009108 case VOS_STA_MODE:
9109 case VOS_P2P_CLIENT_MODE:
9110 case VOS_P2P_GO_MODE:
9111 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009112 pHddCtx->concurrency_mode |= (1 << mode);
9113 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009114 break;
9115 default:
9116 break;
9117
9118 }
9119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9120 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9121}
9122
9123
9124void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9125{
9126 switch(mode)
9127 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009128 case VOS_STA_MODE:
9129 case VOS_P2P_CLIENT_MODE:
9130 case VOS_P2P_GO_MODE:
9131 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009132 pHddCtx->no_of_sessions[mode]--;
9133 if (!(pHddCtx->no_of_sessions[mode]))
9134 pHddCtx->concurrency_mode &= (~(1 << mode));
9135 break;
9136 default:
9137 break;
9138 }
9139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9140 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9141}
9142
Jeff Johnsone7245742012-09-05 17:12:55 -07009143/**---------------------------------------------------------------------------
9144 *
9145 * \brief wlan_hdd_restart_init
9146 *
9147 * This function initalizes restart timer/flag. An internal function.
9148 *
9149 * \param - pHddCtx
9150 *
9151 * \return - None
9152 *
9153 * --------------------------------------------------------------------------*/
9154
9155static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9156{
9157 /* Initialize */
9158 pHddCtx->hdd_restart_retries = 0;
9159 atomic_set(&pHddCtx->isRestartInProgress, 0);
9160 vos_timer_init(&pHddCtx->hdd_restart_timer,
9161 VOS_TIMER_TYPE_SW,
9162 wlan_hdd_restart_timer_cb,
9163 pHddCtx);
9164}
9165/**---------------------------------------------------------------------------
9166 *
9167 * \brief wlan_hdd_restart_deinit
9168 *
9169 * This function cleans up the resources used. An internal function.
9170 *
9171 * \param - pHddCtx
9172 *
9173 * \return - None
9174 *
9175 * --------------------------------------------------------------------------*/
9176
9177static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9178{
9179
9180 VOS_STATUS vos_status;
9181 /* Block any further calls */
9182 atomic_set(&pHddCtx->isRestartInProgress, 1);
9183 /* Cleanup */
9184 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9185 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009186 hddLog(LOGW, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009187 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9188 if (!VOS_IS_STATUS_SUCCESS(vos_status))
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009189 hddLog(LOGW, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009190
9191}
9192
9193/**---------------------------------------------------------------------------
9194 *
9195 * \brief wlan_hdd_framework_restart
9196 *
9197 * This function uses a cfg80211 API to start a framework initiated WLAN
9198 * driver module unload/load.
9199 *
9200 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9201 *
9202 *
9203 * \param - pHddCtx
9204 *
9205 * \return - VOS_STATUS_SUCCESS: Success
9206 * VOS_STATUS_E_EMPTY: Adapter is Empty
9207 * VOS_STATUS_E_NOMEM: No memory
9208
9209 * --------------------------------------------------------------------------*/
9210
9211static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9212{
9213 VOS_STATUS status = VOS_STATUS_SUCCESS;
9214 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009215 int len = (sizeof (struct ieee80211_mgmt));
9216 struct ieee80211_mgmt *mgmt = NULL;
9217
9218 /* Prepare the DEAUTH managment frame with reason code */
9219 mgmt = kzalloc(len, GFP_KERNEL);
9220 if(mgmt == NULL)
9221 {
9222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9223 "%s: memory allocation failed (%d bytes)", __func__, len);
9224 return VOS_STATUS_E_NOMEM;
9225 }
9226 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009227
9228 /* Iterate over all adapters/devices */
9229 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9230 do
9231 {
9232 if( (status == VOS_STATUS_SUCCESS) &&
9233 pAdapterNode &&
9234 pAdapterNode->pAdapter)
9235 {
9236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9237 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9238 pAdapterNode->pAdapter->dev->name,
9239 pAdapterNode->pAdapter->device_mode,
9240 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009241 /*
9242 * CFG80211 event to restart the driver
9243 *
9244 * 'cfg80211_send_unprot_deauth' sends a
9245 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9246 * of SME(Linux Kernel) state machine.
9247 *
9248 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9249 * the driver.
9250 *
9251 */
9252
9253 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009254 }
9255 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9256 pAdapterNode = pNext;
9257 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9258
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009259
9260 /* Free the allocated management frame */
9261 kfree(mgmt);
9262
Jeff Johnsone7245742012-09-05 17:12:55 -07009263 /* Retry until we unload or reach max count */
9264 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9265 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9266
9267 return status;
9268
9269}
9270/**---------------------------------------------------------------------------
9271 *
9272 * \brief wlan_hdd_restart_timer_cb
9273 *
9274 * Restart timer callback. An internal function.
9275 *
9276 * \param - User data:
9277 *
9278 * \return - None
9279 *
9280 * --------------------------------------------------------------------------*/
9281
9282void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9283{
9284 hdd_context_t *pHddCtx = usrDataForCallback;
9285 wlan_hdd_framework_restart(pHddCtx);
9286 return;
9287
9288}
9289
9290
9291/**---------------------------------------------------------------------------
9292 *
9293 * \brief wlan_hdd_restart_driver
9294 *
9295 * This function sends an event to supplicant to restart the WLAN driver.
9296 *
9297 * This function is called from vos_wlanRestart.
9298 *
9299 * \param - pHddCtx
9300 *
9301 * \return - VOS_STATUS_SUCCESS: Success
9302 * VOS_STATUS_E_EMPTY: Adapter is Empty
9303 * VOS_STATUS_E_ALREADY: Request already in progress
9304
9305 * --------------------------------------------------------------------------*/
9306VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9307{
9308 VOS_STATUS status = VOS_STATUS_SUCCESS;
9309
9310 /* A tight check to make sure reentrancy */
9311 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9312 {
9313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9314 "%s: WLAN restart is already in progress", __func__);
9315
9316 return VOS_STATUS_E_ALREADY;
9317 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009318 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009319#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009320 wcnss_reset_intr();
9321#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009322
Jeff Johnsone7245742012-09-05 17:12:55 -07009323 return status;
9324}
9325
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009326/*
9327 * API to find if there is any STA or P2P-Client is connected
9328 */
9329VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9330{
9331 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9332}
Jeff Johnsone7245742012-09-05 17:12:55 -07009333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334//Register the module init/exit functions
9335module_init(hdd_module_init);
9336module_exit(hdd_module_exit);
9337
9338MODULE_LICENSE("Dual BSD/GPL");
9339MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9340MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9341
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009342module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9343 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009344
Jeff Johnson76052702013-04-16 13:55:05 -07009345module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009346 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009347
9348module_param(enable_dfs_chan_scan, int,
9349 S_IRUSR | S_IRGRP | S_IROTH);
9350
9351module_param(enable_11d, int,
9352 S_IRUSR | S_IRGRP | S_IROTH);
9353
9354module_param(country_code, charp,
9355 S_IRUSR | S_IRGRP | S_IROTH);