blob: 4ad62e65e6686a706dfb66ae5dc19668fb770796 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530168static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700169{
170 WLAN_CIPHER_SUITE_WEP40,
171 WLAN_CIPHER_SUITE_WEP104,
172 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800173#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700174#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
175 WLAN_CIPHER_SUITE_KRK,
176 WLAN_CIPHER_SUITE_CCMP,
177#else
178 WLAN_CIPHER_SUITE_CCMP,
179#endif
180#ifdef FEATURE_WLAN_WAPI
181 WLAN_CIPHER_SUITE_SMS4,
182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700183#ifdef WLAN_FEATURE_11W
184 WLAN_CIPHER_SUITE_AES_CMAC,
185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700186};
187
188static inline int is_broadcast_ether_addr(const u8 *addr)
189{
190 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
191 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
192}
193
194static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530195{
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 HDD2GHZCHAN(2412, 1, 0) ,
197 HDD2GHZCHAN(2417, 2, 0) ,
198 HDD2GHZCHAN(2422, 3, 0) ,
199 HDD2GHZCHAN(2427, 4, 0) ,
200 HDD2GHZCHAN(2432, 5, 0) ,
201 HDD2GHZCHAN(2437, 6, 0) ,
202 HDD2GHZCHAN(2442, 7, 0) ,
203 HDD2GHZCHAN(2447, 8, 0) ,
204 HDD2GHZCHAN(2452, 9, 0) ,
205 HDD2GHZCHAN(2457, 10, 0) ,
206 HDD2GHZCHAN(2462, 11, 0) ,
207 HDD2GHZCHAN(2467, 12, 0) ,
208 HDD2GHZCHAN(2472, 13, 0) ,
209 HDD2GHZCHAN(2484, 14, 0) ,
210};
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
213{
214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2437, 6, 0) ,
216 HDD2GHZCHAN(2462, 11, 0) ,
217};
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219static struct ieee80211_channel hdd_channels_5_GHZ[] =
220{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700221 HDD5GHZCHAN(4920, 240, 0) ,
222 HDD5GHZCHAN(4940, 244, 0) ,
223 HDD5GHZCHAN(4960, 248, 0) ,
224 HDD5GHZCHAN(4980, 252, 0) ,
225 HDD5GHZCHAN(5040, 208, 0) ,
226 HDD5GHZCHAN(5060, 212, 0) ,
227 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5180, 36, 0) ,
229 HDD5GHZCHAN(5200, 40, 0) ,
230 HDD5GHZCHAN(5220, 44, 0) ,
231 HDD5GHZCHAN(5240, 48, 0) ,
232 HDD5GHZCHAN(5260, 52, 0) ,
233 HDD5GHZCHAN(5280, 56, 0) ,
234 HDD5GHZCHAN(5300, 60, 0) ,
235 HDD5GHZCHAN(5320, 64, 0) ,
236 HDD5GHZCHAN(5500,100, 0) ,
237 HDD5GHZCHAN(5520,104, 0) ,
238 HDD5GHZCHAN(5540,108, 0) ,
239 HDD5GHZCHAN(5560,112, 0) ,
240 HDD5GHZCHAN(5580,116, 0) ,
241 HDD5GHZCHAN(5600,120, 0) ,
242 HDD5GHZCHAN(5620,124, 0) ,
243 HDD5GHZCHAN(5640,128, 0) ,
244 HDD5GHZCHAN(5660,132, 0) ,
245 HDD5GHZCHAN(5680,136, 0) ,
246 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800247#ifdef FEATURE_WLAN_CH144
248 HDD5GHZCHAN(5720,144, 0) ,
249#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDD5GHZCHAN(5745,149, 0) ,
251 HDD5GHZCHAN(5765,153, 0) ,
252 HDD5GHZCHAN(5785,157, 0) ,
253 HDD5GHZCHAN(5805,161, 0) ,
254 HDD5GHZCHAN(5825,165, 0) ,
255};
256
257static struct ieee80211_rate g_mode_rates[] =
258{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530259 HDD_G_MODE_RATETAB(10, 0x1, 0),
260 HDD_G_MODE_RATETAB(20, 0x2, 0),
261 HDD_G_MODE_RATETAB(55, 0x4, 0),
262 HDD_G_MODE_RATETAB(110, 0x8, 0),
263 HDD_G_MODE_RATETAB(60, 0x10, 0),
264 HDD_G_MODE_RATETAB(90, 0x20, 0),
265 HDD_G_MODE_RATETAB(120, 0x40, 0),
266 HDD_G_MODE_RATETAB(180, 0x80, 0),
267 HDD_G_MODE_RATETAB(240, 0x100, 0),
268 HDD_G_MODE_RATETAB(360, 0x200, 0),
269 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271};
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273static struct ieee80211_rate a_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
283};
284
285static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
286{
287 .channels = hdd_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
303
Jeff Johnson295189b2012-06-20 16:38:30 -0700304static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
305{
306 .channels = hdd_social_channels_2_4_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
308 .band = IEEE80211_BAND_2GHZ,
309 .bitrates = g_mode_rates,
310 .n_bitrates = g_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
316 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
317 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
318 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
319 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
320 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
321};
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
324{
325 .channels = hdd_channels_5_GHZ,
326 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
327 .band = IEEE80211_BAND_5GHZ,
328 .bitrates = a_mode_rates,
329 .n_bitrates = a_mode_rates_size,
330 .ht_cap.ht_supported = 1,
331 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
332 | IEEE80211_HT_CAP_GRN_FLD
333 | IEEE80211_HT_CAP_DSSSCCK40
334 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
335 | IEEE80211_HT_CAP_SGI_40
336 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
337 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
338 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
339 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
340 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
341 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
342};
343
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530344/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 TX/RX direction for each kind of interface */
346static const struct ieee80211_txrx_stypes
347wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
348 [NL80211_IFTYPE_STATION] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
427/* By default, only single channel concurrency is allowed */
428static struct ieee80211_iface_combination
429wlan_hdd_iface_combination = {
430 .limits = wlan_hdd_iface_limit,
431 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800432 /*
433 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
434 * and p2p0 interfaces during driver init
435 * Some vendors create separate interface for P2P operations.
436 * wlan0: STA interface
437 * p2p0: P2P Device interface, action frames goes
438 * through this interface.
439 * p2p-xx: P2P interface, After GO negotiation this interface is
440 * created for p2p operations(GO/CLIENT interface).
441 */
442 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800443 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
444 .beacon_int_infra_match = false,
445};
446#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448static struct cfg80211_ops wlan_hdd_cfg80211_ops;
449
450/* Data rate 100KBPS based on IE Index */
451struct index_data_rate_type
452{
453 v_U8_t beacon_rate_index;
454 v_U16_t supported_rate[4];
455};
456
457/* 11B, 11G Rate table include Basic rate and Extended rate
458 The IDX field is the rate index
459 The HI field is the rate when RSSI is strong or being ignored
460 (in this case we report actual rate)
461 The MID field is the rate when RSSI is moderate
462 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
463 The LO field is the rate when RSSI is low
464 (in this case we don't report rates, actual current rate used)
465 */
466static const struct
467{
468 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700470} supported_data_rate[] =
471{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700472/* IDX HI HM LM LO (RSSI-based index */
473 {2, { 10, 10, 10, 0}},
474 {4, { 20, 20, 10, 0}},
475 {11, { 55, 20, 10, 0}},
476 {12, { 60, 55, 20, 0}},
477 {18, { 90, 55, 20, 0}},
478 {22, {110, 55, 20, 0}},
479 {24, {120, 90, 60, 0}},
480 {36, {180, 120, 60, 0}},
481 {44, {220, 180, 60, 0}},
482 {48, {240, 180, 90, 0}},
483 {66, {330, 180, 90, 0}},
484 {72, {360, 240, 90, 0}},
485 {96, {480, 240, 120, 0}},
486 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700487};
488
489/* MCS Based rate table */
490static struct index_data_rate_type supported_mcs_rate[] =
491{
492/* MCS L20 L40 S20 S40 */
493 {0, {65, 135, 72, 150}},
494 {1, {130, 270, 144, 300}},
495 {2, {195, 405, 217, 450}},
496 {3, {260, 540, 289, 600}},
497 {4, {390, 810, 433, 900}},
498 {5, {520, 1080, 578, 1200}},
499 {6, {585, 1215, 650, 1350}},
500 {7, {650, 1350, 722, 1500}}
501};
502
Leo Chang6f8870f2013-03-26 18:11:36 -0700503#ifdef WLAN_FEATURE_11AC
504
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530505#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700506
507struct index_vht_data_rate_type
508{
509 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510 v_U16_t supported_VHT80_rate[2];
511 v_U16_t supported_VHT40_rate[2];
512 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700513};
514
515typedef enum
516{
517 DATA_RATE_11AC_MAX_MCS_7,
518 DATA_RATE_11AC_MAX_MCS_8,
519 DATA_RATE_11AC_MAX_MCS_9,
520 DATA_RATE_11AC_MAX_MCS_NA
521} eDataRate11ACMaxMcs;
522
523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540extern struct net_device_ops net_ops_struct;
541
Leo Chang9056f462013-08-01 19:21:11 -0700542#ifdef WLAN_NL80211_TESTMODE
543enum wlan_hdd_tm_attr
544{
545 WLAN_HDD_TM_ATTR_INVALID = 0,
546 WLAN_HDD_TM_ATTR_CMD = 1,
547 WLAN_HDD_TM_ATTR_DATA = 2,
548 WLAN_HDD_TM_ATTR_TYPE = 3,
549 /* keep last */
550 WLAN_HDD_TM_ATTR_AFTER_LAST,
551 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
552};
553
554enum wlan_hdd_tm_cmd
555{
556 WLAN_HDD_TM_CMD_WLAN_HB = 1,
557};
558
559#define WLAN_HDD_TM_DATA_MAX_LEN 5000
560
561static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
562{
563 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
564 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
565 .len = WLAN_HDD_TM_DATA_MAX_LEN },
566};
567#endif /* WLAN_NL80211_TESTMODE */
568
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800569#ifdef FEATURE_WLAN_CH_AVOID
570/*
571 * FUNCTION: wlan_hdd_send_avoid_freq_event
572 * This is called when wlan driver needs to send vendor specific
573 * avoid frequency range event to userspace
574 */
575int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
576 tHddAvoidFreqList *pAvoidFreqList)
577{
578 struct sk_buff *vendor_event;
579
580 ENTER();
581
582 if (!pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 "%s: HDD context is null", __func__);
586 return -1;
587 }
588
589 if (!pAvoidFreqList)
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 "%s: pAvoidFreqList is null", __func__);
593 return -1;
594 }
595
596 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
597 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530598 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800599 GFP_KERNEL);
600 if (!vendor_event)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: cfg80211_vendor_event_alloc failed", __func__);
604 return -1;
605 }
606
607 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
608 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
609
610 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
611
612 EXIT();
613 return 0;
614}
615#endif /* FEATURE_WLAN_CH_AVOID */
616
Sunil Duttc69bccb2014-05-26 21:30:20 +0530617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
618
619static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
620 struct sk_buff *vendor_event)
621{
622 if (nla_put_u8(vendor_event,
623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
624 stats->rate.preamble) ||
625 nla_put_u8(vendor_event,
626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
627 stats->rate.nss) ||
628 nla_put_u8(vendor_event,
629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
630 stats->rate.bw) ||
631 nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
633 stats->rate.rateMcsIdx) ||
634 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
635 stats->rate.bitrate ) ||
636 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
637 stats->txMpdu ) ||
638 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
639 stats->rxMpdu ) ||
640 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
641 stats->mpduLost ) ||
642 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
643 stats->retries) ||
644 nla_put_u32(vendor_event,
645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
646 stats->retriesShort ) ||
647 nla_put_u32(vendor_event,
648 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
649 stats->retriesLong))
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("QCA_WLAN_VENDOR_ATTR put fail"));
653 return FALSE;
654 }
655 return TRUE;
656}
657
658static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
659 struct sk_buff *vendor_event)
660{
661 u32 i = 0;
662 struct nlattr *rateInfo;
663 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
664 stats->type) ||
665 nla_put(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
667 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
668 nla_put_u32(vendor_event,
669 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
670 stats->capabilities) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
673 stats->numRate))
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("QCA_WLAN_VENDOR_ATTR put fail"));
677 goto error;
678 }
679
680 rateInfo = nla_nest_start(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
682 for (i = 0; i < stats->numRate; i++)
683 {
684 struct nlattr *rates;
685 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
686 stats->rateStats +
687 (i * sizeof(tSirWifiRateStat)));
688 rates = nla_nest_start(vendor_event, i);
689
690 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR,
693 FL("QCA_WLAN_VENDOR_ATTR put fail"));
694 return FALSE;
695 }
696 nla_nest_end(vendor_event, rates);
697 }
698 nla_nest_end(vendor_event, rateInfo);
699
700 return TRUE;
701error:
702 return FALSE;
703}
704
705static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
706 struct sk_buff *vendor_event)
707{
708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
709 stats->ac ) ||
710 nla_put_u32(vendor_event,
711 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
712 stats->txMpdu ) ||
713 nla_put_u32(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
715 stats->rxMpdu ) ||
716 nla_put_u32(vendor_event,
717 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
718 stats->txMcast ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
721 stats->rxMcast ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
724 stats->rxAmpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
727 stats->txAmpdu ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
730 stats->mpduLost )||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
733 stats->retries ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
736 stats->retriesShort ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
739 stats->retriesLong ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
742 stats->contentionTimeMin ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
745 stats->contentionTimeMax ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
748 stats->contentionTimeAvg ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
751 stats->contentionNumSamples ))
752 {
753 hddLog(VOS_TRACE_LEVEL_ERROR,
754 FL("QCA_WLAN_VENDOR_ATTR put fail") );
755 return FALSE;
756 }
757 return TRUE;
758}
759
760static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
761 struct sk_buff *vendor_event)
762{
763 if (nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
765 nla_put(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
767 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
770 stats->state ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
773 stats->roaming ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
776 stats->capabilities ) ||
777 nla_put(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
779 strlen(stats->ssid), stats->ssid) ||
780 nla_put(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
782 WNI_CFG_BSSID_LEN, stats->bssid) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
785 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
788 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
789 )
790 {
791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("QCA_WLAN_VENDOR_ATTR put fail") );
793 return FALSE;
794 }
795 return TRUE;
796}
797
798static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
799 struct sk_buff *vendor_event)
800{
801 int i = 0;
802 struct nlattr *wmmInfo;
803 if (FALSE == put_wifi_interface_info(
804 &pWifiIfaceStat->info,
805 vendor_event))
806 {
807 hddLog(VOS_TRACE_LEVEL_ERROR,
808 FL("QCA_WLAN_VENDOR_ATTR put fail") );
809 return FALSE;
810
811 }
812
813 if (nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
815 pWifiIfaceStat->beaconRx) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
818 pWifiIfaceStat->mgmtRx) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
821 pWifiIfaceStat->mgmtActionRx) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
824 pWifiIfaceStat->mgmtActionTx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
827 pWifiIfaceStat->rssiMgmt) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
830 pWifiIfaceStat->rssiData) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
833 pWifiIfaceStat->rssiAck))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 return FALSE;
838 }
839
840 wmmInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
842 for (i = 0; i < WIFI_AC_MAX; i++)
843 {
844 struct nlattr *wmmStats;
845 wmmStats = nla_nest_start(vendor_event, i);
846 if (FALSE == put_wifi_wmm_ac_stat(
847 &pWifiIfaceStat->AccessclassStats[i],
848 vendor_event))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
852 return FALSE;
853 }
854
855 nla_nest_end(vendor_event, wmmStats);
856 }
857 nla_nest_end(vendor_event, wmmInfo);
858 return TRUE;
859}
860
861static tSirWifiInterfaceMode
862 hdd_map_device_to_ll_iface_mode ( int deviceMode )
863{
864 switch (deviceMode)
865 {
866 case WLAN_HDD_INFRA_STATION:
867 return WIFI_INTERFACE_STA;
868 case WLAN_HDD_SOFTAP:
869 return WIFI_INTERFACE_SOFTAP;
870 case WLAN_HDD_P2P_CLIENT:
871 return WIFI_INTERFACE_P2P_CLIENT;
872 case WLAN_HDD_P2P_GO:
873 return WIFI_INTERFACE_P2P_GO;
874 case WLAN_HDD_IBSS:
875 return WIFI_INTERFACE_IBSS;
876 default:
877 /* Return Interface Mode as STA for all the unsupported modes */
878 return WIFI_INTERFACE_STA;
879 }
880}
881
882static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
883 tpSirWifiInterfaceInfo pInfo)
884{
885 v_U8_t *staMac = NULL;
886 hdd_station_ctx_t *pHddStaCtx;
887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
888 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
889
890 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
891
892 vos_mem_copy(pInfo->macAddr,
893 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
894
895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
898 {
899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
900 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
901 {
902 pInfo->state = WIFI_DISCONNECTED;
903 }
904 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
905 {
906 hddLog(VOS_TRACE_LEVEL_ERROR,
907 "%s: Session ID %d, Connection is in progress", __func__,
908 pAdapter->sessionId);
909 pInfo->state = WIFI_ASSOCIATING;
910 }
911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
913 {
914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: client " MAC_ADDRESS_STR
917 " is in the middle of WPS/EAPOL exchange.", __func__,
918 MAC_ADDR_ARRAY(staMac));
919 pInfo->state = WIFI_AUTHENTICATING;
920 }
921 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
922 {
923 pInfo->state = WIFI_ASSOCIATED;
924 vos_mem_copy(pInfo->bssid,
925 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
926 vos_mem_copy(pInfo->ssid,
927 pHddStaCtx->conn_info.SSID.SSID.ssId,
928 pHddStaCtx->conn_info.SSID.SSID.length);
929 //NULL Terminate the string.
930 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
931 }
932 }
933 vos_mem_copy(pInfo->countryStr,
934 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
935
936 vos_mem_copy(pInfo->apCountryStr,
937 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
938
939 return TRUE;
940}
941
942/*
943 * hdd_link_layer_process_peer_stats () - This function is called after
944 * receiving Link Layer Peer statistics from FW.This function converts
945 * the firmware data to the NL data and sends the same to the kernel/upper
946 * layers.
947 */
948static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
949 v_VOID_t *pData)
950{
951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
952 tpSirWifiRateStat pWifiRateStat;
953 tpSirWifiPeerStat pWifiPeerStat;
954 tpSirWifiPeerInfo pWifiPeerInfo;
955 struct nlattr *peerInfo;
956 struct sk_buff *vendor_event;
957 int status, i;
958
959 status = wlan_hdd_validate_context(pHddCtx);
960 if (0 != status)
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("HDD context is not valid") );
964 return;
965 }
966
967 pWifiPeerStat = (tpSirWifiPeerStat) pData;
968
969 hddLog(VOS_TRACE_LEVEL_INFO,
970 "LL_STATS_PEER_ALL : numPeers %u",
971 pWifiPeerStat->numPeers);
972 {
973 for (i = 0; i < pWifiPeerStat->numPeers; i++)
974 {
975 pWifiPeerInfo = (tpSirWifiPeerInfo)
976 ((uint8 *)pWifiPeerStat->peerInfo +
977 ( i * sizeof(tSirWifiPeerInfo)));
978
979 hddLog(VOS_TRACE_LEVEL_INFO,
980 " %d) LL_STATS Channel Stats "
981 " Peer Type %u "
982 " peerMacAddress %pM "
983 " capabilities 0x%x "
984 " numRate %u ",
985 i,
986 pWifiPeerInfo->type,
987 pWifiPeerInfo->peerMacAddress,
988 pWifiPeerInfo->capabilities,
989 pWifiPeerInfo->numRate);
990 {
991 int j;
992 for (j = 0; j < pWifiPeerInfo->numRate; j++)
993 {
994 pWifiRateStat = (tpSirWifiRateStat)
995 ((tANI_U8 *) pWifiPeerInfo->rateStats +
996 ( j * sizeof(tSirWifiRateStat)));
997
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 " peer Rate Stats "
1000 " preamble %u "
1001 " nss %u "
1002 " bw %u "
1003 " rateMcsIdx %u "
1004 " reserved %u "
1005 " bitrate %u "
1006 " txMpdu %u "
1007 " rxMpdu %u "
1008 " mpduLost %u "
1009 " retries %u "
1010 " retriesShort %u "
1011 " retriesLong %u",
1012 pWifiRateStat->rate.preamble,
1013 pWifiRateStat->rate.nss,
1014 pWifiRateStat->rate.bw,
1015 pWifiRateStat->rate.rateMcsIdx,
1016 pWifiRateStat->rate.reserved,
1017 pWifiRateStat->rate.bitrate,
1018 pWifiRateStat->txMpdu,
1019 pWifiRateStat->rxMpdu,
1020 pWifiRateStat->mpduLost,
1021 pWifiRateStat->retries,
1022 pWifiRateStat->retriesShort,
1023 pWifiRateStat->retriesLong);
1024 }
1025 }
1026 }
1027 }
1028
1029 /*
1030 * Allocate a size of 4096 for the peer stats comprising
1031 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1032 * sizeof (tSirWifiRateStat).Each field is put with an
1033 * NL attribute.The size of 4096 is considered assuming
1034 * that number of rates shall not exceed beyond 50 with
1035 * the sizeof (tSirWifiRateStat) being 32.
1036 */
1037 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1038 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1039 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1040 GFP_KERNEL);
1041 if (!vendor_event)
1042 {
1043 hddLog(VOS_TRACE_LEVEL_ERROR,
1044 "%s: cfg80211_vendor_event_alloc failed",
1045 __func__);
1046 return;
1047 }
1048 if (nla_put_u32(vendor_event,
1049 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1050 pWifiPeerStat->numPeers))
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1054 kfree_skb(vendor_event);
1055 return;
1056 }
1057
1058 peerInfo = nla_nest_start(vendor_event,
1059 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1060
1061 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1062 pWifiPeerStat->peerInfo);
1063
1064 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1065 {
1066 struct nlattr *peers = nla_nest_start(vendor_event, i);
1067 int numRate = pWifiPeerInfo->numRate;
1068
1069 if (FALSE == put_wifi_peer_info(
1070 pWifiPeerInfo, vendor_event))
1071 {
1072 hddLog(VOS_TRACE_LEVEL_ERROR,
1073 "%s: put_wifi_peer_info put fail", __func__);
1074 kfree_skb(vendor_event);
1075 return;
1076 }
1077
1078 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1079 pWifiPeerStat->peerInfo +
1080 (i * sizeof(tSirWifiPeerInfo)) +
1081 (numRate * sizeof (tSirWifiRateStat)));
1082 nla_nest_end(vendor_event, peers);
1083 }
1084 nla_nest_end(vendor_event, peerInfo);
1085 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1086}
1087
1088/*
1089 * hdd_link_layer_process_iface_stats () - This function is called after
1090 * receiving Link Layer Interface statistics from FW.This function converts
1091 * the firmware data to the NL data and sends the same to the kernel/upper
1092 * layers.
1093 */
1094static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1095 v_VOID_t *pData)
1096{
1097 tpSirWifiIfaceStat pWifiIfaceStat;
1098 struct sk_buff *vendor_event;
1099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1100 int status;
1101
1102 status = wlan_hdd_validate_context(pHddCtx);
1103 if (0 != status)
1104 {
1105 hddLog(VOS_TRACE_LEVEL_ERROR,
1106 FL("HDD context is not valid") );
1107 return;
1108 }
1109 /*
1110 * Allocate a size of 4096 for the interface stats comprising
1111 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1112 * assuming that all these fit with in the limit.Please take
1113 * a call on the limit based on the data requirements on
1114 * interface statistics.
1115 */
1116 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1117 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1118 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1119 GFP_KERNEL);
1120 if (!vendor_event)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR,
1123 FL("cfg80211_vendor_event_alloc failed") );
1124 return;
1125 }
1126
1127 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1128
1129 hddLog(VOS_TRACE_LEVEL_INFO,
1130 "WMI_LINK_STATS_IFACE Data");
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 "LL_STATS_IFACE: "
1134 " Mode %u "
1135 " MAC %pM "
1136 " State %u "
1137 " Roaming %u "
1138 " capabilities 0x%x "
1139 " SSID %s "
1140 " BSSID %pM",
1141 pWifiIfaceStat->info.mode,
1142 pWifiIfaceStat->info.macAddr,
1143 pWifiIfaceStat->info.state,
1144 pWifiIfaceStat->info.roaming,
1145 pWifiIfaceStat->info.capabilities,
1146 pWifiIfaceStat->info.ssid,
1147 pWifiIfaceStat->info.bssid);
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 " AP country str: %c%c%c",
1151 pWifiIfaceStat->info.apCountryStr[0],
1152 pWifiIfaceStat->info.apCountryStr[1],
1153 pWifiIfaceStat->info.apCountryStr[2]);
1154
1155
1156 hddLog(VOS_TRACE_LEVEL_INFO,
1157 " Country Str Association: %c%c%c",
1158 pWifiIfaceStat->info.countryStr[0],
1159 pWifiIfaceStat->info.countryStr[1],
1160 pWifiIfaceStat->info.countryStr[2]);
1161
1162 hddLog(VOS_TRACE_LEVEL_INFO,
1163 " beaconRx %u "
1164 " mgmtRx %u "
1165 " mgmtActionRx %u "
1166 " mgmtActionTx %u "
1167 " rssiMgmt %u "
1168 " rssiData %u "
1169 " rssiAck %u",
1170 pWifiIfaceStat->beaconRx,
1171 pWifiIfaceStat->mgmtRx,
1172 pWifiIfaceStat->mgmtActionRx,
1173 pWifiIfaceStat->mgmtActionTx,
1174 pWifiIfaceStat->rssiMgmt,
1175 pWifiIfaceStat->rssiData,
1176 pWifiIfaceStat->rssiAck );
1177
1178
1179 {
1180 int i;
1181 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_INFO,
1184
1185 " %d) LL_STATS IFACE: "
1186 " ac: %u txMpdu: %u "
1187 " rxMpdu: %u txMcast: %u "
1188 " rxMcast: %u rxAmpdu: %u "
1189 " txAmpdu: %u mpduLost: %u "
1190 " retries: %u retriesShort: %u "
1191 " retriesLong: %u contentionTimeMin: %u "
1192 " contentionTimeMax: %u contentionTimeAvg: %u "
1193 " contentionNumSamples: %u",
1194 i,
1195 pWifiIfaceStat->AccessclassStats[i].ac,
1196 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1197 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1198 pWifiIfaceStat->AccessclassStats[i].txMcast,
1199 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1200 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1201 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1202 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1203 pWifiIfaceStat->AccessclassStats[i].retries,
1204 pWifiIfaceStat->
1205 AccessclassStats[i].retriesShort,
1206 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1207 pWifiIfaceStat->
1208 AccessclassStats[i].contentionTimeMin,
1209 pWifiIfaceStat->
1210 AccessclassStats[i].contentionTimeMax,
1211 pWifiIfaceStat->
1212 AccessclassStats[i].contentionTimeAvg,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].contentionNumSamples);
1215
1216 }
1217 }
1218
1219 if (FALSE == hdd_get_interface_info( pAdapter,
1220 &pWifiIfaceStat->info))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 FL("hdd_get_interface_info get fail") );
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1229 vendor_event))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("put_wifi_iface_stats fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1237}
1238
1239/*
1240 * hdd_link_layer_process_radio_stats () - This function is called after
1241 * receiving Link Layer Radio statistics from FW.This function converts
1242 * the firmware data to the NL data and sends the same to the kernel/upper
1243 * layers.
1244 */
1245static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1246 v_VOID_t *pData)
1247{
1248 int status, i;
1249 tpSirWifiRadioStat pWifiRadioStat;
1250 tpSirWifiChannelStats pWifiChannelStats;
1251 struct sk_buff *vendor_event;
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1253 struct nlattr *chList;
1254
1255 status = wlan_hdd_validate_context(pHddCtx);
1256 if (0 != status)
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("HDD context is not valid") );
1260 return;
1261 }
1262 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1263
1264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 "LL_STATS_RADIO"
1266 " radio is %d onTime is %u "
1267 " txTime is %u rxTime is %u "
1268 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301269 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 " onTimePnoScan is %u onTimeHs20 is %u "
1271 " numChannels is %u",
1272 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1273 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1274 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301275 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301276 pWifiRadioStat->onTimeRoamScan,
1277 pWifiRadioStat->onTimePnoScan,
1278 pWifiRadioStat->onTimeHs20,
1279 pWifiRadioStat->numChannels);
1280 /*
1281 * Allocate a size of 4096 for the Radio stats comprising
1282 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1283 * (tSirWifiChannelStats).Each channel data is put with an
1284 * NL attribute.The size of 4096 is considered assuming that
1285 * number of channels shall not exceed beyond 60 with the
1286 * sizeof (tSirWifiChannelStats) being 24 bytes.
1287 */
1288
1289 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1290 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1291 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1292 GFP_KERNEL);
1293
1294 if (!vendor_event)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 FL("cfg80211_vendor_event_alloc failed") );
1298 return;
1299 }
1300
1301 if (nla_put_u32(vendor_event,
1302 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1303 pWifiRadioStat->radio) ||
1304 nla_put_u32(vendor_event,
1305 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1306 pWifiRadioStat->onTime) ||
1307 nla_put_u32(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1309 pWifiRadioStat->txTime) ||
1310 nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1312 pWifiRadioStat->rxTime) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1315 pWifiRadioStat->onTimeScan) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1318 pWifiRadioStat->onTimeNbd) ||
1319 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1321 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1324 pWifiRadioStat->onTimeRoamScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1327 pWifiRadioStat->onTimePnoScan) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1330 pWifiRadioStat->onTimeHs20) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1333 pWifiRadioStat->numChannels))
1334 {
1335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1337 kfree_skb(vendor_event);
1338 return ;
1339 }
1340
1341 chList = nla_nest_start(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1343 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1344 {
1345 struct nlattr *chInfo;
1346
1347 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1348 pWifiRadioStat->channels +
1349 (i * sizeof(tSirWifiChannelStats)));
1350
1351 hddLog(VOS_TRACE_LEVEL_INFO,
1352 " %d) Channel Info"
1353 " width is %u "
1354 " CenterFreq %u "
1355 " CenterFreq0 %u "
1356 " CenterFreq1 %u "
1357 " onTime %u "
1358 " ccaBusyTime %u",
1359 i,
1360 pWifiChannelStats->channel.width,
1361 pWifiChannelStats->channel.centerFreq,
1362 pWifiChannelStats->channel.centerFreq0,
1363 pWifiChannelStats->channel.centerFreq1,
1364 pWifiChannelStats->onTime,
1365 pWifiChannelStats->ccaBusyTime);
1366
1367
1368 chInfo = nla_nest_start(vendor_event, i);
1369
1370 if (nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1372 pWifiChannelStats->channel.width) ||
1373 nla_put_u32(vendor_event,
1374 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1375 pWifiChannelStats->channel.centerFreq) ||
1376 nla_put_u32(vendor_event,
1377 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1378 pWifiChannelStats->channel.centerFreq0) ||
1379 nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1381 pWifiChannelStats->channel.centerFreq1) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1384 pWifiChannelStats->onTime) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1387 pWifiChannelStats->ccaBusyTime))
1388 {
1389 hddLog(VOS_TRACE_LEVEL_ERROR,
1390 FL("cfg80211_vendor_event_alloc failed") );
1391 kfree_skb(vendor_event);
1392 return ;
1393 }
1394 nla_nest_end(vendor_event, chInfo);
1395 }
1396 nla_nest_end(vendor_event, chList);
1397
1398 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1399 return;
1400}
1401
1402/*
1403 * hdd_link_layer_stats_ind_callback () - This function is called after
1404 * receiving Link Layer indications from FW.This callback converts the firmware
1405 * data to the NL data and send the same to the kernel/upper layers.
1406 */
1407static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1408 int indType,
1409 void *pRsp )
1410{
1411 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCtx;
1412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1413 int status;
1414
1415 status = wlan_hdd_validate_context(pHddCtx);
1416
1417 if (0 != status)
1418 {
1419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 FL("HDD context is not valid"));
1421 return;
1422 }
1423
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1425 "%s: Link Layer Indication indType: %d", __func__, indType);
1426 switch (indType)
1427 {
1428 case SIR_HAL_LL_STATS_RESULTS_RSP:
1429 {
1430 tpSirLLStatsResults linkLayerStatsResults =
1431 (tpSirLLStatsResults)pRsp;
1432
1433
1434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1436 hddLog(VOS_TRACE_LEVEL_INFO,
1437 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1438 linkLayerStatsResults->paramId);
1439 hddLog(VOS_TRACE_LEVEL_INFO,
1440 "LL_STATS RESULTS RESPONSE ifaceId = %u",
1441 linkLayerStatsResults->ifaceId);
1442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "LL_STATS RESULTS RESPONSE respId = %u",
1444 linkLayerStatsResults->respId);
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1447 linkLayerStatsResults->moreResultToFollow);
1448 hddLog(VOS_TRACE_LEVEL_INFO,
1449 "LL_STATS RESULTS RESPONSE result = %p",
1450 linkLayerStatsResults->result);
1451 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1452 {
1453 hdd_link_layer_process_radio_stats(pAdapter,
1454 (v_VOID_t *)linkLayerStatsResults->result);
1455 }
1456 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1457 {
1458 hdd_link_layer_process_iface_stats(pAdapter,
1459 (v_VOID_t *)linkLayerStatsResults->result);
1460 }
1461 else if ( linkLayerStatsResults->paramId &
1462 WMI_LINK_STATS_ALL_PEER )
1463 {
1464 hdd_link_layer_process_peer_stats(pAdapter,
1465 (v_VOID_t *)linkLayerStatsResults->result);
1466 } /* WMI_LINK_STATS_ALL_PEER */
1467 else
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
1470 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1471 }
1472
1473 break;
1474 }
1475 default:
1476 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1477 break;
1478 }
1479 return;
1480}
1481
1482const struct
1483nla_policy
1484qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1485{
1486 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1487 { .type = NLA_U32 },
1488 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1489 { .type = NLA_U32 },
1490};
1491
1492static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1493 struct wireless_dev *wdev,
1494 void *data,
1495 int data_len)
1496{
1497 int status;
1498 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301499 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301500 struct net_device *dev = wdev->netdev;
1501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1503
1504 status = wlan_hdd_validate_context(pHddCtx);
1505 if (0 != status)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("HDD context is not valid"));
1509 return -EINVAL;
1510 }
1511
1512 if (NULL == pAdapter)
1513 {
1514 hddLog(VOS_TRACE_LEVEL_ERROR,
1515 FL("HDD adapter is Null"));
1516 return -ENODEV;
1517 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301518 /* check the LLStats Capability */
1519 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1520 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1521 {
1522 hddLog(VOS_TRACE_LEVEL_ERROR,
1523 FL("Link Layer Statistics not supported by Firmware"));
1524 return -EINVAL;
1525 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301526
1527 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1528 (struct nlattr *)data,
1529 data_len, qca_wlan_vendor_ll_set_policy))
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1532 return -EINVAL;
1533 }
1534 if (!tb_vendor
1535 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1538 return -EINVAL;
1539 }
1540 if (!tb_vendor[
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1542 {
1543 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1544 return -EINVAL;
1545 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301547 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301548
Dino Mycledf0a5d92014-07-04 09:41:55 +05301549 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 nla_get_u32(
1551 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1552
Dino Mycledf0a5d92014-07-04 09:41:55 +05301553 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 nla_get_u32(
1555 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1556
1557 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1558 * Hence the interface staId start from 1. Hence the staId matching the
1559 * interface in the firmware is sessionId + 1.
1560 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301561 linkLayerStatsSetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562
1563
1564 hddLog(VOS_TRACE_LEVEL_INFO,
1565 "LL_STATS_SET reqId = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301566 linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301568 "LL_STATS_SET staId = %d", linkLayerStatsSetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301571 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301574 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
1576 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1577 pHddCtx->hHal,
1578 pAdapter->sessionId,
1579 hdd_link_layer_stats_ind_callback,
1580 pAdapter))
1581 {
1582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1583 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301588 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 return -EINVAL;
1593 }
1594
1595 pAdapter->isLinkLayerStatsSet = 1;
1596
1597 return 0;
1598}
1599
1600const struct
1601nla_policy
1602qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1603{
1604 /* Unsigned 32bit value provided by the caller issuing the GET stats
1605 * command. When reporting
1606 * the stats results, the driver uses the same value to indicate
1607 * which GET request the results
1608 * correspond to.
1609 */
1610 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1611
1612 /* Unsigned 32bit value . bit mask to identify what statistics are
1613 requested for retrieval */
1614 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1615};
1616
1617static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1618 struct wireless_dev *wdev,
1619 void *data,
1620 int data_len)
1621{
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301624 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 struct net_device *dev = wdev->netdev;
1626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1627 int status;
1628
1629 status = wlan_hdd_validate_context(pHddCtx);
1630 if (0 != status)
1631 {
1632 hddLog(VOS_TRACE_LEVEL_ERROR,
1633 FL("HDD context is not valid"));
1634 return -EINVAL ;
1635 }
1636
1637 if (NULL == pAdapter)
1638 {
1639 hddLog(VOS_TRACE_LEVEL_FATAL,
1640 "%s: HDD adapter is Null", __func__);
1641 return -ENODEV;
1642 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301643 /* check the LLStats Capability */
1644 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1645 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1646 {
1647 hddLog(VOS_TRACE_LEVEL_ERROR,
1648 FL("Link Layer Statistics not supported by Firmware"));
1649 return -EINVAL;
1650 }
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652
1653 if (!pAdapter->isLinkLayerStatsSet)
1654 {
1655 hddLog(VOS_TRACE_LEVEL_FATAL,
1656 "%s: isLinkLayerStatsSet : %d",
1657 __func__, pAdapter->isLinkLayerStatsSet);
1658 return -EINVAL;
1659 }
1660
1661 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1662 (struct nlattr *)data,
1663 data_len, qca_wlan_vendor_ll_get_policy))
1664 {
1665 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1666 return -EINVAL;
1667 }
1668
1669 if (!tb_vendor
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1671 {
1672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1673 return -EINVAL;
1674 }
1675
1676 if (!tb_vendor
1677 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1680 return -EINVAL;
1681 }
1682
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683
Dino Mycledf0a5d92014-07-04 09:41:55 +05301684 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 nla_get_u32( tb_vendor[
1689 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1690
1691 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1692 * Hence the interface staId start from 1. Hence the staId matching the
1693 * interface in the firmware is sessionId + 1.
1694 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301695 linkLayerStatsGetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301698 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301699 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 "LL_STATS_GET staId = %d", linkLayerStatsGetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710 return -EINVAL;
1711 }
1712 return 0;
1713}
1714
1715const struct
1716nla_policy
1717qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1718{
1719 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1723};
1724
1725static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1726 struct wireless_dev *wdev,
1727 void *data,
1728 int data_len)
1729{
1730 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1731 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 struct net_device *dev = wdev->netdev;
1734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1735 u32 statsClearReqMask;
1736 u8 stopReq;
1737 int status;
1738
1739 status = wlan_hdd_validate_context(pHddCtx);
1740 if (0 != status)
1741 {
1742 hddLog(VOS_TRACE_LEVEL_ERROR,
1743 FL("HDD context is not valid"));
1744 return -EINVAL;
1745 }
1746
1747 if (NULL == pAdapter)
1748 {
1749 hddLog(VOS_TRACE_LEVEL_FATAL,
1750 "%s: HDD adapter is Null", __func__);
1751 return -ENODEV;
1752 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301753 /* check the LLStats Capability */
1754 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1755 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR,
1758 FL("Enable LLStats Capability"));
1759 return -EINVAL;
1760 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761
1762 if (!pAdapter->isLinkLayerStatsSet)
1763 {
1764 hddLog(VOS_TRACE_LEVEL_FATAL,
1765 "%s: isLinkLayerStatsSet : %d",
1766 __func__, pAdapter->isLinkLayerStatsSet);
1767 return -EINVAL;
1768 }
1769
1770 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1771 (struct nlattr *)data,
1772 data_len, qca_wlan_vendor_ll_clr_policy))
1773 {
1774 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1775 return -EINVAL;
1776 }
1777
1778 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1779
1780 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1781 {
1782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1783 return -EINVAL;
1784
1785 }
1786
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787
Dino Mycledf0a5d92014-07-04 09:41:55 +05301788 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
Dino Mycledf0a5d92014-07-04 09:41:55 +05301792 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301793 nla_get_u8(
1794 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1795
1796 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798
1799 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1800 * Hence the interface staId start from 1. Hence the staId matching the
1801 * interface in the firmware is sessionId + 1.
1802 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301803 linkLayerStatsClearReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301806 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301808 "LL_STATS_CLEAR staId = %d", linkLayerStatsClearReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 struct sk_buff *temp_skbuff;
1820 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1821 2 * sizeof(u32) +
1822 NLMSG_HDRLEN);
1823
1824 if (temp_skbuff != NULL)
1825 {
1826
1827 if (nla_put_u32(temp_skbuff,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1829 statsClearReqMask) ||
1830 nla_put_u32(temp_skbuff,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1832 stopReq))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1835 kfree_skb(temp_skbuff);
1836 return -EINVAL;
1837 }
1838 /* If the ask is to stop the stats collection as part of clear
1839 * (stopReq = 1) , ensure that no further requests of get
1840 * go to the firmware by having isLinkLayerStatsSet set to 0.
1841 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301842 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 * case the firmware is just asked to clear the statistics.
1844 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301845 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301851 return -EINVAL;
1852}
1853#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1854
Dino Mycle6fb96c12014-06-10 11:52:40 +05301855#ifdef WLAN_FEATURE_EXTSCAN
1856static const struct nla_policy
1857wlan_hdd_extscan_config_policy
1858 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1859{
1860 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1861 { .type = NLA_U32 },
1862 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1863 { .type = NLA_U32 },
1864 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1866 { .type = NLA_U32 },
1867 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1869
1870 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1874 { .type = NLA_U8 },
1875 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1876 { .type = NLA_U32 },
1877 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1878 { .type = NLA_U32 },
1879 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1880 { .type = NLA_U32 },
1881 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1882 { .type = NLA_U8 },
1883 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1884 { .type = NLA_U8 },
1885 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1886 { .type = NLA_U8 },
1887
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1889 { .type = NLA_U32 },
1890 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1891 { .type = NLA_UNSPEC },
1892 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1893 { .type = NLA_S32 },
1894 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1895 { .type = NLA_S32 },
1896 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1897 { .type = NLA_U32 },
1898 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1899 { .type = NLA_U32 },
1900 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1901 { .type = NLA_U32 },
1902 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1903 = { .type = NLA_U32 },
1904 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1905 { .type = NLA_U32 },
1906 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1907 NLA_U32 },
1908};
1909
1910static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1911{
1912 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1913 struct sk_buff *skb = NULL;
1914 tpSirEXTScanCapabilitiesEvent pData =
1915 (tpSirEXTScanCapabilitiesEvent) pMsg;
1916
1917 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1919 "or pData(%p) is null"), pData);
1920 return;
1921 }
1922
1923 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1924 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1925 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1926 GFP_KERNEL);
1927
1928 if (!skb) {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("cfg80211_vendor_event_alloc failed"));
1931 return;
1932 }
1933
1934 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1939 pData->maxRssiSampleSize);
1940 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1941 pData->maxScanReportingThreshold);
1942 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1944 pData->maxSignificantWifiChangeAPs);
1945 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1946 pData->maxBsidHistoryEntries);
1947
1948 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1949 pData->requestId) ||
1950 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1951 nla_put_u32(skb,
1952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1953 pData->scanCacheSize) ||
1954 nla_put_u32(skb,
1955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1956 pData->scanBuckets) ||
1957 nla_put_u32(skb,
1958 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1959 pData->maxApPerScan) ||
1960 nla_put_u32(skb,
1961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1962 pData->maxRssiSampleSize) ||
1963 nla_put_u32(skb,
1964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1965 pData->maxScanReportingThreshold) ||
1966 nla_put_u32(skb,
1967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1968 pData->maxHotlistAPs) ||
1969 nla_put_u32(skb,
1970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1971 pData->maxSignificantWifiChangeAPs) ||
1972 nla_put_u32(skb,
1973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1974 pData->maxBsidHistoryEntries)) {
1975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1976 goto nla_put_failure;
1977 }
1978
1979 cfg80211_vendor_event(skb, GFP_KERNEL);
1980 return;
1981
1982nla_put_failure:
1983 kfree_skb(skb);
1984 return;
1985}
1986
1987
1988static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1989{
1990 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1991 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1992 struct sk_buff *skb = NULL;
1993 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1994
1995
1996 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1998 "or pData(%p) is null"), pData);
1999 return;
2000 }
2001
2002 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2003 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2004 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2005 GFP_KERNEL);
2006
2007 if (!skb) {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
2009 FL("cfg80211_vendor_event_alloc failed"));
2010 return;
2011 }
2012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2013 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2015
2016 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2017 pData->requestId) ||
2018 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2020 goto nla_put_failure;
2021 }
2022
2023 /*
2024 * Store the Request ID for comparing with the requestID obtained
2025 * in other requests.HDD shall return a failure is the extscan_stop
2026 * request is issued with a different requestId as that of the
2027 * extscan_start request. Also, This requestId shall be used while
2028 * indicating the full scan results to the upper layers.
2029 * The requestId is stored with the assumption that the firmware
2030 * shall return the ext scan start request's requestId in ext scan
2031 * start response.
2032 */
2033 if (pData->status == 0)
2034 pMac->sme.extScanStartReqId = pData->requestId;
2035
2036
2037 cfg80211_vendor_event(skb, GFP_KERNEL);
2038 return;
2039
2040nla_put_failure:
2041 kfree_skb(skb);
2042 return;
2043}
2044
2045
2046static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2047{
2048 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2049 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2050 struct sk_buff *skb = NULL;
2051
2052 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2054 "or pData(%p) is null"), pData);
2055 return;
2056 }
2057
2058 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2059 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2060 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2061 GFP_KERNEL);
2062
2063 if (!skb) {
2064 hddLog(VOS_TRACE_LEVEL_ERROR,
2065 FL("cfg80211_vendor_event_alloc failed"));
2066 return;
2067 }
2068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2069 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2070
2071 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2072 pData->requestId) ||
2073 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2075 goto nla_put_failure;
2076 }
2077
2078 cfg80211_vendor_event(skb, GFP_KERNEL);
2079 return;
2080
2081nla_put_failure:
2082 kfree_skb(skb);
2083 return;
2084}
2085
2086
2087static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2088 void *pMsg)
2089{
2090 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2091 struct sk_buff *skb = NULL;
2092 tpSirEXTScanSetBssidHotListRspParams pData =
2093 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2094
2095 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2097 "or pData(%p) is null"), pData);
2098 return;
2099 }
2100 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2101 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2102 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2103 GFP_KERNEL);
2104
2105 if (!skb) {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed"));
2108 return;
2109 }
2110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2111 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2113
2114 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2115 pData->requestId) ||
2116 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2118 goto nla_put_failure;
2119 }
2120
2121 cfg80211_vendor_event(skb, GFP_KERNEL);
2122 return;
2123
2124nla_put_failure:
2125 kfree_skb(skb);
2126 return;
2127}
2128
2129static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2130 void *pMsg)
2131{
2132 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2133 struct sk_buff *skb = NULL;
2134 tpSirEXTScanResetBssidHotlistRspParams pData =
2135 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2136
2137 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2139 "or pData(%p) is null"), pData);
2140 return;
2141 }
2142
2143 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2144 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2145 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2146 GFP_KERNEL);
2147
2148 if (!skb) {
2149 hddLog(VOS_TRACE_LEVEL_ERROR,
2150 FL("cfg80211_vendor_event_alloc failed"));
2151 return;
2152 }
2153 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2154 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2155
2156 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2157 pData->requestId) ||
2158 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2160 goto nla_put_failure;
2161 }
2162
2163 cfg80211_vendor_event(skb, GFP_KERNEL);
2164 return;
2165
2166nla_put_failure:
2167 kfree_skb(skb);
2168 return;
2169}
2170
2171
2172static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2173 void *pMsg)
2174{
2175 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2176 struct sk_buff *skb = NULL;
2177 tpSirEXTScanSetSignificantChangeRspParams pData =
2178 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2179
2180 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2182 "or pData(%p) is null"), pData);
2183 return;
2184 }
2185
2186 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2187 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2188 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2189 GFP_KERNEL);
2190
2191 if (!skb) {
2192 hddLog(VOS_TRACE_LEVEL_ERROR,
2193 FL("cfg80211_vendor_event_alloc failed"));
2194 return;
2195 }
2196 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2197 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2199
2200 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2201 pData->requestId) ||
2202 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2204 goto nla_put_failure;
2205 }
2206
2207 cfg80211_vendor_event(skb, GFP_KERNEL);
2208 return;
2209
2210nla_put_failure:
2211 kfree_skb(skb);
2212 return;
2213}
2214
2215
2216static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2217 void *pMsg)
2218{
2219 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2220 struct sk_buff *skb = NULL;
2221 tpSirEXTScanResetSignificantChangeRspParams pData =
2222 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2223
2224 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2226 "or pData(%p) is null"), pData);
2227 return;
2228 }
2229
2230 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2231 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2232 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2233 GFP_KERNEL);
2234
2235 if (!skb) {
2236 hddLog(VOS_TRACE_LEVEL_ERROR,
2237 FL("cfg80211_vendor_event_alloc failed"));
2238 return;
2239 }
2240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2241 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2243
2244 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2245 pData->requestId) ||
2246 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2248 goto nla_put_failure;
2249 }
2250
2251 cfg80211_vendor_event(skb, GFP_KERNEL);
2252 return;
2253
2254nla_put_failure:
2255 kfree_skb(skb);
2256 return;
2257}
2258
2259static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2260 void *pMsg)
2261{
2262 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2263 struct sk_buff *skb = NULL;
2264 tANI_U32 i = 0, j, resultsPerEvent;
2265 tANI_S32 totalResults;
2266 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2267 tpSirWifiScanResult pSirWifiScanResult;
2268
2269 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2271 "or pData(%p) is null"), pData);
2272 return;
2273 }
2274 totalResults = pData->numOfAps;
2275 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2278
2279 do{
2280 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2281 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2282 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2283
2284 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2285 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2286 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2287 GFP_KERNEL);
2288
2289 if (!skb) {
2290 hddLog(VOS_TRACE_LEVEL_ERROR,
2291 FL("cfg80211_vendor_event_alloc failed"));
2292 return;
2293 }
2294
2295 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2296
2297 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2298 pData->requestId) ||
2299 nla_put_u32(skb,
2300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2301 resultsPerEvent)) {
2302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2303 goto fail;
2304 }
2305 if (nla_put_u8(skb,
2306 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2307 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2308 {
2309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2310 goto fail;
2311 }
2312
2313 if (resultsPerEvent) {
2314 struct nlattr *aps;
2315
2316 aps = nla_nest_start(skb,
2317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2318 if (!aps)
2319 {
2320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2321 goto fail;
2322 }
2323
2324 for (j = 0; j < resultsPerEvent; j++, i++) {
2325 struct nlattr *ap;
2326 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2327 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2328
2329 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2330 "Ssid (%s)"
2331 "Bssid: %pM "
2332 "Channel (%u)"
2333 "Rssi (%d)"
2334 "RTT (%u)"
2335 "RTT_SD (%u)",
2336 i,
2337 pSirWifiScanResult->ts,
2338 pSirWifiScanResult->ssid,
2339 pSirWifiScanResult->bssid,
2340 pSirWifiScanResult->channel,
2341 pSirWifiScanResult->rssi,
2342 pSirWifiScanResult->rtt,
2343 pSirWifiScanResult->rtt_sd);
2344
2345 ap = nla_nest_start(skb, j + 1);
2346 if (!ap)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2349 goto fail;
2350 }
2351
2352 if (nla_put_u64(skb,
2353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2354 pSirWifiScanResult->ts) )
2355 {
2356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2357 goto fail;
2358 }
2359 if (nla_put(skb,
2360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2361 sizeof(pSirWifiScanResult->ssid),
2362 pSirWifiScanResult->ssid) )
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2365 goto fail;
2366 }
2367 if (nla_put(skb,
2368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2369 sizeof(pSirWifiScanResult->bssid),
2370 pSirWifiScanResult->bssid) )
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2373 goto fail;
2374 }
2375 if (nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2377 pSirWifiScanResult->channel) )
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2380 goto fail;
2381 }
2382 if (nla_put_u32(skb,
2383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2384 pSirWifiScanResult->rssi) )
2385 {
2386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2387 goto fail;
2388 }
2389 if (nla_put_u32(skb,
2390 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2391 pSirWifiScanResult->rtt) )
2392 {
2393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2394 goto fail;
2395 }
2396 if (nla_put_u32(skb,
2397 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2398 pSirWifiScanResult->rtt_sd))
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2401 goto fail;
2402 }
2403
2404 nla_nest_end(skb, ap);
2405 }
2406 nla_nest_end(skb, aps);
2407
2408 }
2409 cfg80211_vendor_event(skb, GFP_KERNEL);
2410 } while (totalResults > 0);
2411
2412 return;
2413fail:
2414 kfree_skb(skb);
2415 return;
2416}
2417
2418static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2419 void *pMsg)
2420{
2421 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2422 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2423 struct sk_buff *skb = NULL;
2424 tANI_U32 i;
2425
2426 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2428 "or pData(%p) is null"), pData);
2429 return;
2430 }
2431
2432 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2433 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2434 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2435 GFP_KERNEL);
2436
2437 if (!skb) {
2438 hddLog(VOS_TRACE_LEVEL_ERROR,
2439 FL("cfg80211_vendor_event_alloc failed"));
2440 return;
2441 }
2442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2443 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2446
2447 for (i = 0; i < pData->numOfAps; i++) {
2448 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2449 "Ssid (%s) "
2450 "Bssid (" MAC_ADDRESS_STR ") "
2451 "Channel (%u) "
2452 "Rssi (%d) "
2453 "RTT (%u) "
2454 "RTT_SD (%u) ",
2455 i,
2456 pData->ap[i].ts,
2457 pData->ap[i].ssid,
2458 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2459 pData->ap[i].channel,
2460 pData->ap[i].rssi,
2461 pData->ap[i].rtt,
2462 pData->ap[i].rtt_sd);
2463 }
2464
2465 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2466 pData->requestId) ||
2467 nla_put_u32(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2469 pData->numOfAps)) {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2471 goto fail;
2472 }
2473 if (pData->numOfAps) {
2474 struct nlattr *aps;
2475
2476 aps = nla_nest_start(skb,
2477 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2478 if (!aps)
2479 goto fail;
2480
2481 for (i = 0; i < pData->numOfAps; i++) {
2482 struct nlattr *ap;
2483
2484 ap = nla_nest_start(skb, i + 1);
2485 if (!ap)
2486 goto fail;
2487
2488 if (nla_put_u64(skb,
2489 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2490 pData->ap[i].ts) ||
2491 nla_put(skb,
2492 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2493 sizeof(pData->ap[i].ssid),
2494 pData->ap[i].ssid) ||
2495 nla_put(skb,
2496 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2497 sizeof(pData->ap[i].bssid),
2498 pData->ap[i].bssid) ||
2499 nla_put_u32(skb,
2500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2501 pData->ap[i].channel) ||
2502 nla_put_s32(skb,
2503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2504 pData->ap[i].rssi) ||
2505 nla_put_u32(skb,
2506 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2507 pData->ap[i].rtt) ||
2508 nla_put_u32(skb,
2509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2510 pData->ap[i].rtt_sd))
2511 goto fail;
2512
2513 nla_nest_end(skb, ap);
2514 }
2515 nla_nest_end(skb, aps);
2516
2517 if (nla_put_u8(skb,
2518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2519 pData->moreData))
2520 goto fail;
2521 }
2522
2523 cfg80211_vendor_event(skb, GFP_KERNEL);
2524 return;
2525
2526fail:
2527 kfree_skb(skb);
2528 return;
2529
2530}
2531static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2532 void *pMsg)
2533{
2534 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2535 struct sk_buff *skb = NULL;
2536 tANI_U32 i, j;
2537 tpSirWifiSignificantChangeEvent pData =
2538 (tpSirWifiSignificantChangeEvent) pMsg;
2539
2540 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2542 "or pData(%p) is null"), pData);
2543 return;
2544 }
2545 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2546 EXTSCAN_EVENT_BUF_SIZE,
2547 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2548 GFP_KERNEL);
2549
2550 if (!skb) {
2551 hddLog(VOS_TRACE_LEVEL_ERROR,
2552 FL("cfg80211_vendor_event_alloc failed"));
2553 return;
2554 }
2555 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2556 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2557 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2558 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2559 pData->numSigRssiBss);
2560 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2561
2562 for (i = 0; i < pData->numSigRssiBss; i++) {
2563 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2564 " num RSSI %u ",
2565 i, pData->sigRssiResult[i].bssid,
2566 pData->sigRssiResult[i].channel,
2567 pData->sigRssiResult[i].numRssi);
2568
2569 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2570
2571 hddLog(VOS_TRACE_LEVEL_INFO,
2572 " [%d]",
2573 pData->sigRssiResult[i].rssi[0]);
2574
2575 }
2576 }
2577
2578
2579 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2580 pData->requestId) ||
2581 nla_put_u32(skb,
2582 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2583 pData->numSigRssiBss)) {
2584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2585 goto fail;
2586 }
2587
2588 if (pData->numSigRssiBss) {
2589 struct nlattr *aps;
2590 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2591 if (!aps)
2592 goto fail;
2593 for (i = 0; i < pData->numSigRssiBss; i++) {
2594 struct nlattr *ap;
2595
2596 ap = nla_nest_start(skb, i);
2597 if (!ap)
2598 goto fail;
2599 if (nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2601 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2602 nla_put_u32(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2604 pData->sigRssiResult[i].channel) ||
2605 nla_put_u32(skb,
2606 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2607 pData->sigRssiResult[i].numRssi) ||
2608 nla_put(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2610 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2611 pData->sigRssiResult[i].rssi))
2612 goto fail;
2613 nla_nest_end(skb, ap);
2614 }
2615 nla_nest_end(skb, aps);
2616 if (nla_put_u8(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2618 pData->moreData))
2619 goto fail;
2620 }
2621 cfg80211_vendor_event(skb, GFP_KERNEL);
2622 return;
2623fail:
2624 kfree_skb(skb);
2625 return;
2626}
2627
2628static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2629 void *pMsg)
2630{
2631 struct sk_buff *skb;
2632 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2633 tpSirWifiFullScanResultEvent pData =
2634 (tpSirWifiFullScanResultEvent) (pMsg);
2635
2636 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2638 "or pData(%p) is null"), pData);
2639 return;
2640 }
2641
2642 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2643 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2644 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2645 GFP_KERNEL);
2646
2647 if (!skb) {
2648 hddLog(VOS_TRACE_LEVEL_ERROR,
2649 FL("cfg80211_vendor_event_alloc failed"));
2650 return;
2651 }
2652
2653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2657 "Ssid (%s)"
2658 "Bssid (" MAC_ADDRESS_STR ")"
2659 "Channel (%u)"
2660 "Rssi (%d)"
2661 "RTT (%u)"
2662 "RTT_SD (%u)"),
2663 pData->ap.ts,
2664 pData->ap.ssid,
2665 MAC_ADDR_ARRAY(pData->ap.bssid),
2666 pData->ap.channel,
2667 pData->ap.rssi,
2668 pData->ap.rtt,
2669 pData->ap.rtt_sd);
2670 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2672 pData->requestId) ||
2673 nla_put_u64(skb,
2674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2675 pData->ap.ts) ||
2676 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2677 sizeof(pData->ap.ssid),
2678 pData->ap.ssid) ||
2679 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2680 WNI_CFG_BSSID_LEN,
2681 pData->ap.bssid) ||
2682 nla_put_u32(skb,
2683 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2684 pData->ap.channel) ||
2685 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2686 pData->ap.rssi) ||
2687 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2688 pData->ap.rtt) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2691 pData->ap.rtt_sd) ||
2692 nla_put_u16(skb,
2693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2694 pData->ap.beaconPeriod) ||
2695 nla_put_u16(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2697 pData->ap.capability) ||
2698 nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2700 pData->ieLength))
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2703 goto nla_put_failure;
2704 }
2705 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2706 pData->ieLength,
2707 pData->ie))
2708 {
2709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2710 goto nla_put_failure;
2711 }
2712
2713 cfg80211_vendor_event(skb, GFP_KERNEL);
2714 return;
2715
2716nla_put_failure:
2717 kfree_skb(skb);
2718 return;
2719}
2720
2721static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2722 void *pMsg)
2723{
2724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2725 struct sk_buff *skb = NULL;
2726 tpSirEXTScanResultsAvailableIndParams pData =
2727 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2728
2729 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2731 "or pData(%p) is null"), pData);
2732 return;
2733 }
2734
2735 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2736 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2737 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2738 GFP_KERNEL);
2739
2740 if (!skb) {
2741 hddLog(VOS_TRACE_LEVEL_ERROR,
2742 FL("cfg80211_vendor_event_alloc failed"));
2743 return;
2744 }
2745
2746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2747 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2749 pData->numResultsAvailable);
2750 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2751 pData->requestId) ||
2752 nla_put_u32(skb,
2753 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2754 pData->numResultsAvailable)) {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2756 goto nla_put_failure;
2757 }
2758
2759 cfg80211_vendor_event(skb, GFP_KERNEL);
2760 return;
2761
2762nla_put_failure:
2763 kfree_skb(skb);
2764 return;
2765}
2766
2767static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2768{
2769 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2770 struct sk_buff *skb = NULL;
2771 tpSirEXTScanProgressIndParams pData =
2772 (tpSirEXTScanProgressIndParams) pMsg;
2773
2774 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2776 "or pData(%p) is null"), pData);
2777 return;
2778 }
2779
2780 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2781 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2782 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2783 GFP_KERNEL);
2784
2785 if (!skb) {
2786 hddLog(VOS_TRACE_LEVEL_ERROR,
2787 FL("cfg80211_vendor_event_alloc failed"));
2788 return;
2789 }
2790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2791 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2792 pData->extScanEventType);
2793 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2794 pData->status);
2795
2796 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2797 pData->extScanEventType) ||
2798 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2800 pData->requestId) ||
2801 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2803 pData->status)) {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2805 goto nla_put_failure;
2806 }
2807
2808 cfg80211_vendor_event(skb, GFP_KERNEL);
2809 return;
2810
2811nla_put_failure:
2812 kfree_skb(skb);
2813 return;
2814}
2815
2816void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2817 void *pMsg)
2818{
2819 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2820
2821 if (wlan_hdd_validate_context(pHddCtx)) {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2823 return;
2824 }
2825
2826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2827
2828
2829 switch(evType) {
2830 case SIR_HAL_EXTSCAN_START_RSP:
2831 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2832 break;
2833
2834 case SIR_HAL_EXTSCAN_STOP_RSP:
2835 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2836 break;
2837 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2838 /* There is no need to send this response to upper layer
2839 Just log the message */
2840 hddLog(VOS_TRACE_LEVEL_INFO,
2841 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2842 break;
2843 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2844 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2845 break;
2846
2847 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2848 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2849 break;
2850
2851 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2852 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2853 break;
2854
2855 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2856 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2857 break;
2858 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2859 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2860 break;
2861 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2862 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2863 break;
2864 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2865 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2866 break;
2867 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2868 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2869 break;
2870 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2871 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2872 break;
2873 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2874 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2875 break;
2876 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2877 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2878 break;
2879 default:
2880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2881 break;
2882 }
2883}
2884
2885static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2886 struct wireless_dev *wdev,
2887 void *data, int dataLen)
2888{
Dino Myclee8843b32014-07-04 14:21:45 +05302889 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890 struct net_device *dev = wdev->netdev;
2891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2893 struct nlattr
2894 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2895 eHalStatus status;
2896
2897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2898 status = wlan_hdd_validate_context(pHddCtx);
2899 if (0 != status)
2900 {
2901 hddLog(VOS_TRACE_LEVEL_ERROR,
2902 FL("HDD context is not valid"));
2903 return -EINVAL;
2904 }
Dino Myclee8843b32014-07-04 14:21:45 +05302905 /* check the EXTScan Capability */
2906 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2907 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2908 {
2909 hddLog(VOS_TRACE_LEVEL_ERROR,
2910 FL("EXTScan not enabled/supported by Firmware"));
2911 return -EINVAL;
2912 }
2913
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2915 data, dataLen,
2916 wlan_hdd_extscan_config_policy)) {
2917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2918 return -EINVAL;
2919 }
2920
2921 /* Parse and fetch request Id */
2922 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2924 return -EINVAL;
2925 }
2926
Dino Mycle6fb96c12014-06-10 11:52:40 +05302927
Dino Myclee8843b32014-07-04 14:21:45 +05302928 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931
Dino Myclee8843b32014-07-04 14:21:45 +05302932 reqMsg.sessionId = pAdapter->sessionId;
2933 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Dino Myclee8843b32014-07-04 14:21:45 +05302935 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302936 if (!HAL_STATUS_SUCCESS(status)) {
2937 hddLog(VOS_TRACE_LEVEL_ERROR,
2938 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return -EINVAL;
2940 }
2941
2942 return 0;
2943}
2944
2945
2946static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2947 struct wireless_dev *wdev,
2948 void *data, int dataLen)
2949{
Dino Myclee8843b32014-07-04 14:21:45 +05302950 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302951 struct net_device *dev = wdev->netdev;
2952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2953 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2954 struct nlattr
2955 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2956 eHalStatus status;
2957
2958 status = wlan_hdd_validate_context(pHddCtx);
2959 if (0 != status)
2960 {
2961 hddLog(VOS_TRACE_LEVEL_ERROR,
2962 FL("HDD context is not valid"));
2963 return -EINVAL;
2964 }
Dino Myclee8843b32014-07-04 14:21:45 +05302965 /* check the EXTScan Capability */
2966 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2967 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2968 {
2969 hddLog(VOS_TRACE_LEVEL_ERROR,
2970 FL("EXTScan not enabled/supported by Firmware"));
2971 return -EINVAL;
2972 }
2973
Dino Mycle6fb96c12014-06-10 11:52:40 +05302974 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2975 data, dataLen,
2976 wlan_hdd_extscan_config_policy)) {
2977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2978 return -EINVAL;
2979 }
2980 /* Parse and fetch request Id */
2981 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2983 return -EINVAL;
2984 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302985
Dino Myclee8843b32014-07-04 14:21:45 +05302986 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302987 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2988
Dino Myclee8843b32014-07-04 14:21:45 +05302989 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990
Dino Myclee8843b32014-07-04 14:21:45 +05302991 reqMsg.sessionId = pAdapter->sessionId;
2992 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993
2994 /* Parse and fetch flush parameter */
2995 if (!tb
2996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2997 {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2999 goto failed;
3000 }
Dino Myclee8843b32014-07-04 14:21:45 +05303001 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3003
Dino Myclee8843b32014-07-04 14:21:45 +05303004 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303005
Dino Myclee8843b32014-07-04 14:21:45 +05303006 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303007 if (!HAL_STATUS_SUCCESS(status)) {
3008 hddLog(VOS_TRACE_LEVEL_ERROR,
3009 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 return -EINVAL;
3011 }
3012 return 0;
3013
3014failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303015 return -EINVAL;
3016}
3017
3018static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3019 struct wireless_dev *wdev,
3020 void *data, int dataLen)
3021{
3022 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3023 struct net_device *dev = wdev->netdev;
3024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3025 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3026 struct nlattr
3027 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3028 struct nlattr
3029 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3030 struct nlattr *apTh;
3031 eHalStatus status;
3032 tANI_U8 i = 0;
3033 int rem;
3034
3035 status = wlan_hdd_validate_context(pHddCtx);
3036 if (0 != status)
3037 {
3038 hddLog(VOS_TRACE_LEVEL_ERROR,
3039 FL("HDD context is not valid"));
3040 return -EINVAL;
3041 }
Dino Myclee8843b32014-07-04 14:21:45 +05303042 /* check the EXTScan Capability */
3043 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3044 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3045 {
3046 hddLog(VOS_TRACE_LEVEL_ERROR,
3047 FL("EXTScan not enabled/supported by Firmware"));
3048 return -EINVAL;
3049 }
3050
Dino Mycle6fb96c12014-06-10 11:52:40 +05303051 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3052 data, dataLen,
3053 wlan_hdd_extscan_config_policy)) {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3055 return -EINVAL;
3056 }
3057
3058 /* Parse and fetch request Id */
3059 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3061 return -EINVAL;
3062 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303063 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3064 vos_mem_malloc(sizeof(*pReqMsg));
3065 if (!pReqMsg) {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3067 return -ENOMEM;
3068 }
3069
Dino Myclee8843b32014-07-04 14:21:45 +05303070
Dino Mycle6fb96c12014-06-10 11:52:40 +05303071 pReqMsg->requestId = nla_get_u32(
3072 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3074
3075 /* Parse and fetch number of APs */
3076 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3078 goto fail;
3079 }
3080
3081 pReqMsg->sessionId = pAdapter->sessionId;
3082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3083
3084 pReqMsg->numAp = nla_get_u32(
3085 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3087
3088 nla_for_each_nested(apTh,
3089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3090 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3091 nla_data(apTh), nla_len(apTh),
3092 NULL)) {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3094 goto fail;
3095 }
3096
3097 /* Parse and fetch MAC address */
3098 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3100 goto fail;
3101 }
3102 memcpy(pReqMsg->ap[i].bssid, nla_data(
3103 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3104 sizeof(tSirMacAddr));
3105 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3106
3107 /* Parse and fetch low RSSI */
3108 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3110 goto fail;
3111 }
3112 pReqMsg->ap[i].low = nla_get_s32(
3113 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3114 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3115
3116 /* Parse and fetch high RSSI */
3117 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3119 goto fail;
3120 }
3121 pReqMsg->ap[i].high = nla_get_s32(
3122 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3123 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3124 pReqMsg->ap[i].high);
3125
3126 /* Parse and fetch channel */
3127 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3129 goto fail;
3130 }
3131 pReqMsg->ap[i].channel = nla_get_u32(
3132 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3133 hddLog(VOS_TRACE_LEVEL_INFO,
3134 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3135 i++;
3136 }
3137 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3138 if (!HAL_STATUS_SUCCESS(status)) {
3139 hddLog(VOS_TRACE_LEVEL_ERROR,
3140 FL("sme_SetBssHotlist failed(err=%d)"), status);
3141 vos_mem_free(pReqMsg);
3142 return -EINVAL;
3143 }
3144
Dino Myclee8843b32014-07-04 14:21:45 +05303145 vos_mem_free(pReqMsg);
3146
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return 0;
3148
3149fail:
3150 vos_mem_free(pReqMsg);
3151 return -EINVAL;
3152}
3153
3154static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3155 struct wireless_dev *wdev,
3156 void *data, int dataLen)
3157{
3158 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3159 struct net_device *dev = wdev->netdev;
3160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3161 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3162 struct nlattr
3163 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3164 struct nlattr
3165 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3166 struct nlattr *apTh;
3167 eHalStatus status;
3168 int i = 0;
3169 int rem;
3170
3171 status = wlan_hdd_validate_context(pHddCtx);
3172 if (0 != status)
3173 {
3174 hddLog(VOS_TRACE_LEVEL_ERROR,
3175 FL("HDD context is not valid"));
3176 return -EINVAL;
3177 }
Dino Myclee8843b32014-07-04 14:21:45 +05303178 /* check the EXTScan Capability */
3179 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3180 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3181 {
3182 hddLog(VOS_TRACE_LEVEL_ERROR,
3183 FL("EXTScan not enabled/supported by Firmware"));
3184 return -EINVAL;
3185 }
3186
Dino Mycle6fb96c12014-06-10 11:52:40 +05303187 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3188 data, dataLen,
3189 wlan_hdd_extscan_config_policy)) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3191 return -EINVAL;
3192 }
3193
3194 /* Parse and fetch request Id */
3195 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3197 return -EINVAL;
3198 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303199 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303200 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3203 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204 }
3205
Dino Myclee8843b32014-07-04 14:21:45 +05303206
3207
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 pReqMsg->requestId = nla_get_u32(
3209 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3211
3212 /* Parse and fetch RSSI sample size */
3213 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3214 {
3215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3216 goto fail;
3217 }
3218 pReqMsg->rssiSampleSize = nla_get_u32(
3219 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3220 hddLog(VOS_TRACE_LEVEL_INFO,
3221 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3222
3223 /* Parse and fetch lost AP sample size */
3224 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3225 {
3226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3227 goto fail;
3228 }
3229 pReqMsg->lostApSampleSize = nla_get_u32(
3230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3231 hddLog(VOS_TRACE_LEVEL_INFO,
3232 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3233 /* Parse and fetch minimum Breaching */
3234 if (!tb
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3237 goto fail;
3238 }
3239 pReqMsg->minBreaching = nla_get_u32(
3240 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3241 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3242
3243 /* Parse and fetch number of APs */
3244 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3246 goto fail;
3247 }
3248 pReqMsg->numAp = nla_get_u32(
3249 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3251
3252 pReqMsg->sessionId = pAdapter->sessionId;
3253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3254
3255 nla_for_each_nested(apTh,
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3257 if(nla_parse(tb2,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3259 nla_data(apTh), nla_len(apTh),
3260 NULL)) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3262 goto fail;
3263 }
3264
3265 /* Parse and fetch MAC address */
3266 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3268 goto fail;
3269 }
3270 memcpy(pReqMsg->ap[i].bssid, nla_data(
3271 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3272 sizeof(tSirMacAddr));
3273
3274 /* Parse and fetch low RSSI */
3275 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3277 goto fail;
3278 }
3279 pReqMsg->ap[i].low = nla_get_s32(
3280 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3281 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3282
3283 /* Parse and fetch high RSSI */
3284 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3286 goto fail;
3287 }
3288 pReqMsg->ap[i].high = nla_get_s32(
3289 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3290 hddLog(VOS_TRACE_LEVEL_INFO,
3291 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3292
3293 /* Parse and fetch channel */
3294 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3296 goto fail;
3297 }
3298 pReqMsg->ap[i].channel = nla_get_u32(
3299 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3300 hddLog(VOS_TRACE_LEVEL_INFO,
3301 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3302 i++;
3303 }
3304
3305 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3306 if (!HAL_STATUS_SUCCESS(status)) {
3307 hddLog(VOS_TRACE_LEVEL_ERROR,
3308 FL("sme_SetSignificantChange failed(err=%d)"), status);
3309 vos_mem_free(pReqMsg);
3310 return -EINVAL;
3311 }
Dino Myclee8843b32014-07-04 14:21:45 +05303312 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303313 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3314 return 0;
3315
3316fail:
3317 vos_mem_free(pReqMsg);
3318 return -EINVAL;
3319}
3320
3321static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3322 struct wireless_dev *wdev,
3323 void *data, int dataLen)
3324{
3325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3326 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3327 tANI_U8 numChannels = 0;
3328 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3329 tANI_U32 requestId;
3330 tWifiBand wifiBand;
3331 eHalStatus status;
3332 struct sk_buff *replySkb;
3333 tANI_U8 i;
3334
3335 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3336 status = wlan_hdd_validate_context(pHddCtx);
3337 if (0 != status)
3338 {
3339 hddLog(VOS_TRACE_LEVEL_ERROR,
3340 FL("HDD context is not valid"));
3341 return -EINVAL;
3342 }
Dino Myclee8843b32014-07-04 14:21:45 +05303343 /* check the EXTScan Capability */
3344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3346 {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("EXTScan not enabled/supported by Firmware"));
3349 return -EINVAL;
3350 }
3351
Dino Mycle6fb96c12014-06-10 11:52:40 +05303352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3353 data, dataLen,
3354 wlan_hdd_extscan_config_policy)) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3356 return -EINVAL;
3357 }
3358
3359 /* Parse and fetch request Id */
3360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3362 return -EINVAL;
3363 }
3364 requestId = nla_get_u32(
3365 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3367
3368 /* Parse and fetch wifi band */
3369 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3370 {
3371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3372 return -EINVAL;
3373 }
3374 wifiBand = nla_get_u32(
3375 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3376 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3377
3378 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3379 wifiBand, ChannelList,
3380 &numChannels);
3381 if (eHAL_STATUS_SUCCESS != status) {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3384 return -EINVAL;
3385 }
3386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3387 for (i = 0; i < numChannels; i++)
3388 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3389
3390 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3391 sizeof(u32) * numChannels +
3392 NLMSG_HDRLEN);
3393
3394 if (!replySkb) {
3395 hddLog(VOS_TRACE_LEVEL_ERROR,
3396 FL("valid channels: buffer alloc fail"));
3397 return -EINVAL;
3398 }
3399 if (nla_put_u32(replySkb,
3400 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3401 numChannels) ||
3402 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3403 sizeof(u32) * numChannels, ChannelList)) {
3404
3405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3406 kfree_skb(replySkb);
3407 return -EINVAL;
3408 }
3409
3410 return cfg80211_vendor_cmd_reply(replySkb);
3411}
3412
3413static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3414 struct wireless_dev *wdev,
3415 void *data, int dataLen)
3416{
Dino Myclee8843b32014-07-04 14:21:45 +05303417 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 struct net_device *dev = wdev->netdev;
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3421 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3422 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3423 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3424 struct nlattr *buckets;
3425 struct nlattr *channels;
3426 int rem1;
3427 int rem2;
3428 eHalStatus status;
3429 tANI_U8 bktIndex;
3430 tANI_U32 i = 0, j = 0;
3431
3432 status = wlan_hdd_validate_context(pHddCtx);
3433 if (0 != status)
3434 {
3435 hddLog(VOS_TRACE_LEVEL_ERROR,
3436 FL("HDD context is not valid"));
3437 return -EINVAL;
3438 }
Dino Myclee8843b32014-07-04 14:21:45 +05303439 /* check the EXTScan Capability */
3440 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3441 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3442 {
3443 hddLog(VOS_TRACE_LEVEL_ERROR,
3444 FL("EXTScan not enabled/supported by Firmware"));
3445 return -EINVAL;
3446 }
3447
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3449 data, dataLen,
3450 wlan_hdd_extscan_config_policy)) {
3451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3452 return -EINVAL;
3453 }
3454
3455 /* Parse and fetch request Id */
3456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3458 return -EINVAL;
3459 }
3460
Dino Myclee8843b32014-07-04 14:21:45 +05303461 pReqMsg = (tpSirEXTScanStartReqParams)
3462 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3465 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 }
3467
3468 pReqMsg->requestId = nla_get_u32(
3469 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3470 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3471
3472 pReqMsg->sessionId = pAdapter->sessionId;
3473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3474
3475 /* Parse and fetch base period */
3476 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3478 goto fail;
3479 }
3480 pReqMsg->basePeriod = nla_get_u32(
3481 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3483 pReqMsg->basePeriod);
3484
3485 /* Parse and fetch max AP per scan */
3486 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3488 goto fail;
3489 }
3490 pReqMsg->maxAPperScan = nla_get_u32(
3491 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3492 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3493 pReqMsg->maxAPperScan);
3494
3495 /* Parse and fetch report threshold */
3496 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3498 goto fail;
3499 }
3500 pReqMsg->reportThreshold = nla_get_u8(
3501 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3502 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3503 pReqMsg->reportThreshold);
3504
3505 /* Parse and fetch number of buckets */
3506 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3508 goto fail;
3509 }
3510 pReqMsg->numBuckets = nla_get_u8(
3511 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3512 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3513 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3514 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3515 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3516 }
3517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3518 pReqMsg->numBuckets);
3519 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3521 goto fail;
3522 }
3523
3524 nla_for_each_nested(buckets,
3525 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3526 if(nla_parse(bucket,
3527 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3528 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3530 goto fail;
3531 }
3532
3533 /* Parse and fetch bucket spec */
3534 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3536 goto fail;
3537 }
3538 bktIndex = nla_get_u8(
3539 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3540 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3541 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3542
3543 /* Parse and fetch wifi band */
3544 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3546 goto fail;
3547 }
3548 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3549 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3551 pReqMsg->buckets[bktIndex].band);
3552
3553 /* Parse and fetch period */
3554 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3556 goto fail;
3557 }
3558 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3559 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3560 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3561 pReqMsg->buckets[bktIndex].period);
3562
3563 /* Parse and fetch report events */
3564 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3566 goto fail;
3567 }
3568 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3569 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3570 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3571 pReqMsg->buckets[bktIndex].reportEvents);
3572
3573 /* Parse and fetch number of channels */
3574 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3576 goto fail;
3577 }
3578 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3579 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3580 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3581 pReqMsg->buckets[bktIndex].numChannels);
3582
3583 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3585 goto fail;
3586 }
3587
3588 j = 0;
3589 nla_for_each_nested(channels,
3590 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3591 if(nla_parse(channel,
3592 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3593 nla_data(channels), nla_len(channels),
3594 NULL)) { //wlan_hdd_extscan_config_policy here
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3596 goto fail;
3597 }
3598
3599 /* Parse and fetch channel */
3600 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3602 goto fail;
3603 }
3604 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3605 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3606 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3607 pReqMsg->buckets[bktIndex].channels[j].channel);
3608
3609 /* Parse and fetch dwell time */
3610 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3612 goto fail;
3613 }
3614 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3615 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3617 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3618
3619 /* Parse and fetch channel spec passive */
3620 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3621 hddLog(VOS_TRACE_LEVEL_ERROR,
3622 FL("attr channel spec passive failed"));
3623 goto fail;
3624 }
3625 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3626 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3628 pReqMsg->buckets[bktIndex].channels[j].passive);
3629 j++;
3630 }
3631 i++;
3632 }
3633 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_EXTScanStart failed(err=%d)"), status);
3637 vos_mem_free(pReqMsg);
3638 return -EINVAL;
3639 }
3640
Dino Myclee8843b32014-07-04 14:21:45 +05303641 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642 return 0;
3643
3644fail:
3645 vos_mem_free(pReqMsg);
3646 return -EINVAL;
3647}
3648
3649static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3650 struct wireless_dev *wdev,
3651 void *data, int dataLen)
3652{
Dino Myclee8843b32014-07-04 14:21:45 +05303653 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 struct net_device *dev = wdev->netdev;
3655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3657 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3658 eHalStatus status;
3659
3660 status = wlan_hdd_validate_context(pHddCtx);
3661 if (0 != status)
3662 {
3663 hddLog(VOS_TRACE_LEVEL_ERROR,
3664 FL("HDD context is not valid"));
3665 return -EINVAL;
3666 }
Dino Myclee8843b32014-07-04 14:21:45 +05303667 /* check the EXTScan Capability */
3668 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3669 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3670 {
3671 hddLog(VOS_TRACE_LEVEL_ERROR,
3672 FL("EXTScan not enabled/supported by Firmware"));
3673 return -EINVAL;
3674 }
3675
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3677 data, dataLen,
3678 wlan_hdd_extscan_config_policy)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3680 return -EINVAL;
3681 }
3682
3683 /* Parse and fetch request Id */
3684 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3686 return -EINVAL;
3687 }
3688
Dino Myclee8843b32014-07-04 14:21:45 +05303689 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303690 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303691 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
Dino Myclee8843b32014-07-04 14:21:45 +05303693 reqMsg.sessionId = pAdapter->sessionId;
3694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695
Dino Myclee8843b32014-07-04 14:21:45 +05303696 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303697 if (!HAL_STATUS_SUCCESS(status)) {
3698 hddLog(VOS_TRACE_LEVEL_ERROR,
3699 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303700 return -EINVAL;
3701 }
3702
3703 return 0;
3704}
3705
3706static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3707 struct wireless_dev *wdev,
3708 void *data, int dataLen)
3709{
Dino Myclee8843b32014-07-04 14:21:45 +05303710 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 struct net_device *dev = wdev->netdev;
3712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3713 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3714 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3715 eHalStatus status;
3716
3717 status = wlan_hdd_validate_context(pHddCtx);
3718 if (0 != status)
3719 {
3720 hddLog(VOS_TRACE_LEVEL_ERROR,
3721 FL("HDD context is not valid"));
3722 return -EINVAL;
3723 }
Dino Myclee8843b32014-07-04 14:21:45 +05303724 /* check the EXTScan Capability */
3725 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3726 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3727 {
3728 hddLog(VOS_TRACE_LEVEL_ERROR,
3729 FL("EXTScan not enabled/supported by Firmware"));
3730 return -EINVAL;
3731 }
3732
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3734 data, dataLen,
3735 wlan_hdd_extscan_config_policy)) {
3736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3737 return -EINVAL;
3738 }
3739
3740 /* Parse and fetch request Id */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3743 return -EINVAL;
3744 }
3745
Dino Myclee8843b32014-07-04 14:21:45 +05303746 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749
Dino Myclee8843b32014-07-04 14:21:45 +05303750 reqMsg.sessionId = pAdapter->sessionId;
3751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752
Dino Myclee8843b32014-07-04 14:21:45 +05303753 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303754 if (!HAL_STATUS_SUCCESS(status)) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 return -EINVAL;
3758 }
3759
3760 return 0;
3761}
3762
3763static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3764 struct wiphy *wiphy,
3765 struct wireless_dev *wdev,
3766 void *data, int dataLen)
3767{
Dino Myclee8843b32014-07-04 14:21:45 +05303768 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 struct net_device *dev = wdev->netdev;
3770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3772 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3773 eHalStatus status;
3774
3775 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3776 status = wlan_hdd_validate_context(pHddCtx);
3777 if (0 != status)
3778 {
3779 hddLog(VOS_TRACE_LEVEL_ERROR,
3780 FL("HDD context is not valid"));
3781 return -EINVAL;
3782 }
Dino Myclee8843b32014-07-04 14:21:45 +05303783 /* check the EXTScan Capability */
3784 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3785 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("EXTScan not enabled/supported by Firmware"));
3789 return -EINVAL;
3790 }
3791
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3793 data, dataLen,
3794 wlan_hdd_extscan_config_policy)) {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3796 return -EINVAL;
3797 }
3798
3799 /* Parse and fetch request Id */
3800 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3802 return -EINVAL;
3803 }
3804
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809
Dino Myclee8843b32014-07-04 14:21:45 +05303810 reqMsg.sessionId = pAdapter->sessionId;
3811 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
Dino Myclee8843b32014-07-04 14:21:45 +05303813 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 if (!HAL_STATUS_SUCCESS(status)) {
3815 hddLog(VOS_TRACE_LEVEL_ERROR,
3816 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 return -EINVAL;
3818 }
3819
3820 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3821 return 0;
3822}
3823
3824#endif /* WLAN_FEATURE_EXTSCAN */
3825
Sunil Duttc69bccb2014-05-26 21:30:20 +05303826const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3827{
3828#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3829 {
3830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3833 WIPHY_VENDOR_CMD_NEED_NETDEV |
3834 WIPHY_VENDOR_CMD_NEED_RUNNING,
3835 .doit = wlan_hdd_cfg80211_ll_stats_clear
3836 },
3837
3838 {
3839 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3840 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3841 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3842 WIPHY_VENDOR_CMD_NEED_NETDEV |
3843 WIPHY_VENDOR_CMD_NEED_RUNNING,
3844 .doit = wlan_hdd_cfg80211_ll_stats_set
3845 },
3846
3847 {
3848 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3849 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3850 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3851 WIPHY_VENDOR_CMD_NEED_NETDEV |
3852 WIPHY_VENDOR_CMD_NEED_RUNNING,
3853 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303855#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303856#ifdef WLAN_FEATURE_EXTSCAN
3857 {
3858 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3859 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3860 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3861 WIPHY_VENDOR_CMD_NEED_NETDEV |
3862 WIPHY_VENDOR_CMD_NEED_RUNNING,
3863 .doit = wlan_hdd_cfg80211_extscan_start
3864 },
3865 {
3866 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3867 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3868 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3869 WIPHY_VENDOR_CMD_NEED_NETDEV |
3870 WIPHY_VENDOR_CMD_NEED_RUNNING,
3871 .doit = wlan_hdd_cfg80211_extscan_stop
3872 },
3873 {
3874 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3875 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3876 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3877 WIPHY_VENDOR_CMD_NEED_NETDEV,
3878 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3879 },
3880 {
3881 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3882 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3883 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3884 WIPHY_VENDOR_CMD_NEED_NETDEV |
3885 WIPHY_VENDOR_CMD_NEED_RUNNING,
3886 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3887 },
3888 {
3889 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3890 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3891 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3892 WIPHY_VENDOR_CMD_NEED_NETDEV |
3893 WIPHY_VENDOR_CMD_NEED_RUNNING,
3894 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3895 },
3896 {
3897 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3898 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3899 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3900 WIPHY_VENDOR_CMD_NEED_NETDEV |
3901 WIPHY_VENDOR_CMD_NEED_RUNNING,
3902 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3903 },
3904 {
3905 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3906 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3907 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3908 WIPHY_VENDOR_CMD_NEED_NETDEV |
3909 WIPHY_VENDOR_CMD_NEED_RUNNING,
3910 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3911 },
3912 {
3913 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3914 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3915 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3916 WIPHY_VENDOR_CMD_NEED_NETDEV |
3917 WIPHY_VENDOR_CMD_NEED_RUNNING,
3918 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3919 },
3920 {
3921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3924 WIPHY_VENDOR_CMD_NEED_NETDEV |
3925 WIPHY_VENDOR_CMD_NEED_RUNNING,
3926 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3927 },
3928#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303929};
3930
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003931/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303932static const
3933struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003934{
3935#ifdef FEATURE_WLAN_CH_AVOID
3936 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303937 .vendor_id = QCA_NL80211_VENDOR_ID,
3938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003939 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303940#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3941#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3942 {
3943 /* Index = 1*/
3944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3946 },
3947 {
3948 /* Index = 2*/
3949 .vendor_id = QCA_NL80211_VENDOR_ID,
3950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3951 },
3952 {
3953 /* Index = 3*/
3954 .vendor_id = QCA_NL80211_VENDOR_ID,
3955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3956 },
3957 {
3958 /* Index = 4*/
3959 .vendor_id = QCA_NL80211_VENDOR_ID,
3960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3961 },
3962 {
3963 /* Index = 5*/
3964 .vendor_id = QCA_NL80211_VENDOR_ID,
3965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3966 },
3967 {
3968 /* Index = 6*/
3969 .vendor_id = QCA_NL80211_VENDOR_ID,
3970 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3971 },
3972#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973#ifdef WLAN_FEATURE_EXTSCAN
3974 {
3975 .vendor_id = QCA_NL80211_VENDOR_ID,
3976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3977 },
3978 {
3979 .vendor_id = QCA_NL80211_VENDOR_ID,
3980 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3981 },
3982 {
3983 .vendor_id = QCA_NL80211_VENDOR_ID,
3984 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3985 },
3986 {
3987 .vendor_id = QCA_NL80211_VENDOR_ID,
3988 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3989 },
3990 {
3991 .vendor_id = QCA_NL80211_VENDOR_ID,
3992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3993 },
3994 {
3995 .vendor_id = QCA_NL80211_VENDOR_ID,
3996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3997 },
3998 {
3999 .vendor_id = QCA_NL80211_VENDOR_ID,
4000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4001 },
4002 {
4003 .vendor_id = QCA_NL80211_VENDOR_ID,
4004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4005 },
4006 {
4007 .vendor_id = QCA_NL80211_VENDOR_ID,
4008 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4009 },
4010 {
4011 .vendor_id = QCA_NL80211_VENDOR_ID,
4012 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4013 },
4014 {
4015 .vendor_id = QCA_NL80211_VENDOR_ID,
4016 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4017 },
4018 {
4019 .vendor_id = QCA_NL80211_VENDOR_ID,
4020 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4021 },
4022 {
4023 .vendor_id = QCA_NL80211_VENDOR_ID,
4024 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4025 },
4026#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304027
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004028};
4029
Jeff Johnson295189b2012-06-20 16:38:30 -07004030/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304031 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304032 * This function is called by hdd_wlan_startup()
4033 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304034 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004035 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304036struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004037{
4038 struct wiphy *wiphy;
4039 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304040 /*
4041 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 */
4043 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4044
4045 if (!wiphy)
4046 {
4047 /* Print error and jump into err label and free the memory */
4048 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4049 return NULL;
4050 }
4051
Sunil Duttc69bccb2014-05-26 21:30:20 +05304052
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 return wiphy;
4054}
4055
4056/*
4057 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304058 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004059 * private ioctl to change the band value
4060 */
4061int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4062{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304063 int i, j;
4064 eNVChannelEnabledType channelEnabledState;
4065
Jeff Johnsone7245742012-09-05 17:12:55 -07004066 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304067
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304068 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304070
4071 if (NULL == wiphy->bands[i])
4072 {
4073 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4074 __func__, i);
4075 continue;
4076 }
4077
4078 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4079 {
4080 struct ieee80211_supported_band *band = wiphy->bands[i];
4081
4082 channelEnabledState = vos_nv_getChannelEnabledState(
4083 band->channels[j].hw_value);
4084
4085 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4086 {
4087 // Enable Social channels for P2P
4088 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4089 NV_CHANNEL_ENABLE == channelEnabledState)
4090 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4091 else
4092 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4093 continue;
4094 }
4095 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4096 {
4097 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4098 continue;
4099 }
4100
4101 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4102 NV_CHANNEL_INVALID == channelEnabledState)
4103 {
4104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4105 }
4106 else if (NV_CHANNEL_DFS == channelEnabledState)
4107 {
4108 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4109 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4110 }
4111 else
4112 {
4113 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4114 |IEEE80211_CHAN_RADAR);
4115 }
4116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 }
4118 return 0;
4119}
4120/*
4121 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304122 * This function is called by hdd_wlan_startup()
4123 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 * This function is used to initialize and register wiphy structure.
4125 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304126int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004127 struct wiphy *wiphy,
4128 hdd_config_t *pCfg
4129 )
4130{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304131 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304132 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4133
Jeff Johnsone7245742012-09-05 17:12:55 -07004134 ENTER();
4135
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 /* Now bind the underlying wlan device with wiphy */
4137 set_wiphy_dev(wiphy, dev);
4138
4139 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140
Kiet Lam6c583332013-10-14 05:37:09 +05304141#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004142 /* the flag for the other case would be initialzed in
4143 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004144 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304145#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004146
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147 /* This will disable updating of NL channels from passive to
4148 * active if a beacon is received on passive channel. */
4149 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004150
Amar Singhalfddc28c2013-09-05 13:03:40 -07004151
Amar Singhala49cbc52013-10-08 18:37:44 -07004152
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004154 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4155 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4156 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004157 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304158 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004159#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004160
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004161#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004162 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004163#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004164 || pCfg->isFastRoamIniFeatureEnabled
4165#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004166#ifdef FEATURE_WLAN_ESE
4167 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004168#endif
4169 )
4170 {
4171 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4172 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004173#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004174#ifdef FEATURE_WLAN_TDLS
4175 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4176 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4177#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304178#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304179 if (pCfg->configPNOScanSupport)
4180 {
4181 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4182 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4183 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4184 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4185 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304186#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004187
Amar Singhalfddc28c2013-09-05 13:03:40 -07004188#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004189 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4190 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004191 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004192 driver need to determine what to do with both
4193 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004194
4195 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004196#else
4197 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004198#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304200 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4201
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304202 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004203
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304204 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4205
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304207 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004208 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4210 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004211 | BIT(NL80211_IFTYPE_AP);
4212
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304213 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004214 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4216 if( pCfg->enableMCC )
4217 {
4218 /* Currently, supports up to two channels */
4219 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004220
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304221 if( !pCfg->allowMCCGODiffBI )
4222 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004223
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304224 }
4225 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4226 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004227#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304228 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004229
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 /* Before registering we need to update the ht capabilitied based
4231 * on ini values*/
4232 if( !pCfg->ShortGI20MhzEnable )
4233 {
4234 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4235 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4236 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4237 }
4238
4239 if( !pCfg->ShortGI40MhzEnable )
4240 {
4241 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4242 }
4243
4244 if( !pCfg->nChannelBondingMode5GHz )
4245 {
4246 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4247 }
4248
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304249 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304250 if (true == hdd_is_5g_supported(pHddCtx))
4251 {
4252 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4253 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304254
4255 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4256 {
4257
4258 if (NULL == wiphy->bands[i])
4259 {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4261 __func__, i);
4262 continue;
4263 }
4264
4265 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4266 {
4267 struct ieee80211_supported_band *band = wiphy->bands[i];
4268
4269 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4270 {
4271 // Enable social channels for P2P
4272 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4273 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4274 else
4275 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4276 continue;
4277 }
4278 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4279 {
4280 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4281 continue;
4282 }
4283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 }
4285 /*Initialise the supported cipher suite details*/
4286 wiphy->cipher_suites = hdd_cipher_suites;
4287 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4288
4289 /*signal strength in mBm (100*dBm) */
4290 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4291
4292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304293 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004294#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004295
Sunil Duttc69bccb2014-05-26 21:30:20 +05304296 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4297 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004298 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4299 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4300
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304301 EXIT();
4302 return 0;
4303}
4304
4305/* In this function we are registering wiphy. */
4306int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4307{
4308 ENTER();
4309 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004310 if (0 > wiphy_register(wiphy))
4311 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304312 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004313 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4314 return -EIO;
4315 }
4316
4317 EXIT();
4318 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304319}
Jeff Johnson295189b2012-06-20 16:38:30 -07004320
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304321/* In this function we are updating channel list when,
4322 regulatory domain is FCC and country code is US.
4323 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4324 As per FCC smart phone is not a indoor device.
4325 GO should not opeate on indoor channels */
4326void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4327{
4328 int j;
4329 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4330 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4331 //Default counrtycode from NV at the time of wiphy initialization.
4332 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4333 &defaultCountryCode[0]))
4334 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004335 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304336 }
4337 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4338 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304339 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4340 {
4341 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4342 return;
4343 }
4344 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4345 {
4346 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4347 // Mark UNII -1 band channel as passive
4348 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4349 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4350 }
4351 }
4352}
4353
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304354/* This function registers for all frame which supplicant is interested in */
4355void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004356{
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4358 /* Register for all P2P action, public action etc frames */
4359 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4360
Jeff Johnsone7245742012-09-05 17:12:55 -07004361 ENTER();
4362
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 /* Right now we are registering these frame when driver is getting
4364 initialized. Once we will move to 2.6.37 kernel, in which we have
4365 frame register ops, we will move this code as a part of that */
4366 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304367 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004368 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4369
4370 /* GAS Initial Response */
4371 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4372 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304373
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 /* GAS Comeback Request */
4375 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4376 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4377
4378 /* GAS Comeback Response */
4379 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4380 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4381
4382 /* P2P Public Action */
4383 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304384 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004385 P2P_PUBLIC_ACTION_FRAME_SIZE );
4386
4387 /* P2P Action */
4388 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4389 (v_U8_t*)P2P_ACTION_FRAME,
4390 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004391
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304392 /* WNM BSS Transition Request frame */
4393 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4394 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4395 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004396
4397 /* WNM-Notification */
4398 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4399 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4400 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004401}
4402
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304403void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004404{
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4406 /* Register for all P2P action, public action etc frames */
4407 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4408
Jeff Johnsone7245742012-09-05 17:12:55 -07004409 ENTER();
4410
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 /* Right now we are registering these frame when driver is getting
4412 initialized. Once we will move to 2.6.37 kernel, in which we have
4413 frame register ops, we will move this code as a part of that */
4414 /* GAS Initial Request */
4415
4416 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4417 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4418
4419 /* GAS Initial Response */
4420 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4421 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304422
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 /* GAS Comeback Request */
4424 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4425 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4426
4427 /* GAS Comeback Response */
4428 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4429 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4430
4431 /* P2P Public Action */
4432 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304433 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004434 P2P_PUBLIC_ACTION_FRAME_SIZE );
4435
4436 /* P2P Action */
4437 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4438 (v_U8_t*)P2P_ACTION_FRAME,
4439 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004440 /* WNM-Notification */
4441 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4442 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4443 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004444}
4445
4446#ifdef FEATURE_WLAN_WAPI
4447void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4448 const u8 *mac_addr, u8 *key , int key_Len)
4449{
4450 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4451 tCsrRoamSetKey setKey;
4452 v_BOOL_t isConnected = TRUE;
4453 int status = 0;
4454 v_U32_t roamId= 0xFF;
4455 tANI_U8 *pKeyPtr = NULL;
4456 int n = 0;
4457
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4459 __func__, hdd_device_modetoString(pAdapter->device_mode),
4460 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004461
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304462 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 setKey.keyId = key_index; // Store Key ID
4464 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4465 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4466 setKey.paeRole = 0 ; // the PAE role
4467 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4468 {
4469 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4470 }
4471 else
4472 {
4473 isConnected = hdd_connIsConnected(pHddStaCtx);
4474 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4475 }
4476 setKey.keyLength = key_Len;
4477 pKeyPtr = setKey.Key;
4478 memcpy( pKeyPtr, key, key_Len);
4479
Arif Hussain6d2a3322013-11-17 19:50:10 -08004480 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004481 __func__, key_Len);
4482 for (n = 0 ; n < key_Len; n++)
4483 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4484 __func__,n,setKey.Key[n]);
4485
4486 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4487 if ( isConnected )
4488 {
4489 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4490 pAdapter->sessionId, &setKey, &roamId );
4491 }
4492 if ( status != 0 )
4493 {
4494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4495 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4496 __LINE__, status );
4497 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4498 }
4499}
4500#endif /* FEATURE_WLAN_WAPI*/
4501
4502#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304503int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 beacon_data_t **ppBeacon,
4505 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004506#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304507int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004508 beacon_data_t **ppBeacon,
4509 struct cfg80211_beacon_data *params,
4510 int dtim_period)
4511#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304512{
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 int size;
4514 beacon_data_t *beacon = NULL;
4515 beacon_data_t *old = NULL;
4516 int head_len,tail_len;
4517
Jeff Johnsone7245742012-09-05 17:12:55 -07004518 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004519 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304520 {
4521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4522 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004523 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004525
4526 old = pAdapter->sessionCtx.ap.beacon;
4527
4528 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304529 {
4530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4531 FL("session(%d) old and new heads points to NULL"),
4532 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004533 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304534 }
4535
4536 if (params->tail && !params->tail_len)
4537 {
4538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4539 FL("tail_len is zero but tail is not NULL"));
4540 return -EINVAL;
4541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004542
Jeff Johnson295189b2012-06-20 16:38:30 -07004543#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4544 /* Kernel 3.0 is not updating dtim_period for set beacon */
4545 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304546 {
4547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4548 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304550 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004551#endif
4552
4553 if(params->head)
4554 head_len = params->head_len;
4555 else
4556 head_len = old->head_len;
4557
4558 if(params->tail || !old)
4559 tail_len = params->tail_len;
4560 else
4561 tail_len = old->tail_len;
4562
4563 size = sizeof(beacon_data_t) + head_len + tail_len;
4564
4565 beacon = kzalloc(size, GFP_KERNEL);
4566
4567 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304568 {
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4570 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004573
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004574#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 if(params->dtim_period || !old )
4576 beacon->dtim_period = params->dtim_period;
4577 else
4578 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004579#else
4580 if(dtim_period || !old )
4581 beacon->dtim_period = dtim_period;
4582 else
4583 beacon->dtim_period = old->dtim_period;
4584#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304585
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4587 beacon->tail = beacon->head + head_len;
4588 beacon->head_len = head_len;
4589 beacon->tail_len = tail_len;
4590
4591 if(params->head) {
4592 memcpy (beacon->head,params->head,beacon->head_len);
4593 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304594 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004595 if(old)
4596 memcpy (beacon->head,old->head,beacon->head_len);
4597 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304598
Jeff Johnson295189b2012-06-20 16:38:30 -07004599 if(params->tail) {
4600 memcpy (beacon->tail,params->tail,beacon->tail_len);
4601 }
4602 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304603 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004604 memcpy (beacon->tail,old->tail,beacon->tail_len);
4605 }
4606
4607 *ppBeacon = beacon;
4608
4609 kfree(old);
4610
4611 return 0;
4612
4613}
Jeff Johnson295189b2012-06-20 16:38:30 -07004614
4615v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4616{
4617 int left = length;
4618 v_U8_t *ptr = pIes;
4619 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304620
Jeff Johnson295189b2012-06-20 16:38:30 -07004621 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304622 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 elem_id = ptr[0];
4624 elem_len = ptr[1];
4625 left -= 2;
4626 if(elem_len > left)
4627 {
4628 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004629 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 eid,elem_len,left);
4631 return NULL;
4632 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304633 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 {
4635 return ptr;
4636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304637
Jeff Johnson295189b2012-06-20 16:38:30 -07004638 left -= elem_len;
4639 ptr += (elem_len + 2);
4640 }
4641 return NULL;
4642}
4643
Jeff Johnson295189b2012-06-20 16:38:30 -07004644/* Check if rate is 11g rate or not */
4645static int wlan_hdd_rate_is_11g(u8 rate)
4646{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004647 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 u8 i;
4649 for (i = 0; i < 8; i++)
4650 {
4651 if(rate == gRateArray[i])
4652 return TRUE;
4653 }
4654 return FALSE;
4655}
4656
4657/* Check for 11g rate and set proper 11g only mode */
4658static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4659 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4660{
4661 u8 i, num_rates = pIe[0];
4662
4663 pIe += 1;
4664 for ( i = 0; i < num_rates; i++)
4665 {
4666 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4667 {
4668 /* If rate set have 11g rate than change the mode to 11G */
4669 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4670 if (pIe[i] & BASIC_RATE_MASK)
4671 {
4672 /* If we have 11g rate as basic rate, it means mode
4673 is 11g only mode.
4674 */
4675 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4676 *pCheckRatesfor11g = FALSE;
4677 }
4678 }
4679 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4680 {
4681 *require_ht = TRUE;
4682 }
4683 }
4684 return;
4685}
4686
4687static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4688{
4689 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4690 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4691 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4692 u8 checkRatesfor11g = TRUE;
4693 u8 require_ht = FALSE;
4694 u8 *pIe=NULL;
4695
4696 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4697
4698 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4699 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4700 if (pIe != NULL)
4701 {
4702 pIe += 1;
4703 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4704 &pConfig->SapHw_mode);
4705 }
4706
4707 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4708 WLAN_EID_EXT_SUPP_RATES);
4709 if (pIe != NULL)
4710 {
4711
4712 pIe += 1;
4713 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4714 &pConfig->SapHw_mode);
4715 }
4716
4717 if( pConfig->channel > 14 )
4718 {
4719 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4720 }
4721
4722 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4723 WLAN_EID_HT_CAPABILITY);
4724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304725 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004726 {
4727 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4728 if(require_ht)
4729 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4730 }
4731}
4732
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304733static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4734 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4735{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004736 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304737 v_U8_t *pIe = NULL;
4738 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4739
4740 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4741 pBeacon->tail, pBeacon->tail_len);
4742
4743 if (pIe)
4744 {
4745 ielen = pIe[1] + 2;
4746 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4747 {
4748 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4749 }
4750 else
4751 {
4752 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4753 return -EINVAL;
4754 }
4755 *total_ielen += ielen;
4756 }
4757 return 0;
4758}
4759
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004760static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4761 v_U8_t *genie, v_U8_t *total_ielen)
4762{
4763 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4764 int left = pBeacon->tail_len;
4765 v_U8_t *ptr = pBeacon->tail;
4766 v_U8_t elem_id, elem_len;
4767 v_U16_t ielen = 0;
4768
4769 if ( NULL == ptr || 0 == left )
4770 return;
4771
4772 while (left >= 2)
4773 {
4774 elem_id = ptr[0];
4775 elem_len = ptr[1];
4776 left -= 2;
4777 if (elem_len > left)
4778 {
4779 hddLog( VOS_TRACE_LEVEL_ERROR,
4780 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4781 elem_id, elem_len, left);
4782 return;
4783 }
4784 if (IE_EID_VENDOR == elem_id)
4785 {
4786 /* skipping the VSIE's which we don't want to include or
4787 * it will be included by existing code
4788 */
4789 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4790#ifdef WLAN_FEATURE_WFD
4791 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4792#endif
4793 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4794 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4795 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4796 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4797 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4798 {
4799 ielen = ptr[1] + 2;
4800 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4801 {
4802 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4803 *total_ielen += ielen;
4804 }
4805 else
4806 {
4807 hddLog( VOS_TRACE_LEVEL_ERROR,
4808 "IE Length is too big "
4809 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4810 elem_id, elem_len, *total_ielen);
4811 }
4812 }
4813 }
4814
4815 left -= elem_len;
4816 ptr += (elem_len + 2);
4817 }
4818 return;
4819}
4820
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004821#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004822static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4823 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004824#else
4825static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4826 struct cfg80211_beacon_data *params)
4827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004828{
4829 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304830 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004832 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004833
4834 genie = vos_mem_malloc(MAX_GENIE_LEN);
4835
4836 if(genie == NULL) {
4837
4838 return -ENOMEM;
4839 }
4840
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304841 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4842 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304844 hddLog(LOGE,
4845 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304846 ret = -EINVAL;
4847 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 }
4849
4850#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304851 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4852 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4853 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304854 hddLog(LOGE,
4855 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304856 ret = -EINVAL;
4857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004858 }
4859#endif
4860
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304861 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4862 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304864 hddLog(LOGE,
4865 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304866 ret = -EINVAL;
4867 goto done;
4868 }
4869
4870 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4871 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004872 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004874
4875 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4876 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4877 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4878 {
4879 hddLog(LOGE,
4880 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004881 ret = -EINVAL;
4882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004883 }
4884
4885 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4886 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4887 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4888 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4889 ==eHAL_STATUS_FAILURE)
4890 {
4891 hddLog(LOGE,
4892 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004893 ret = -EINVAL;
4894 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004895 }
4896
4897 // Added for ProResp IE
4898 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4899 {
4900 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4901 u8 probe_rsp_ie_len[3] = {0};
4902 u8 counter = 0;
4903 /* Check Probe Resp Length if it is greater then 255 then Store
4904 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4905 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4906 Store More then 255 bytes into One Variable.
4907 */
4908 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4909 {
4910 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4911 {
4912 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4913 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4914 }
4915 else
4916 {
4917 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4918 rem_probe_resp_ie_len = 0;
4919 }
4920 }
4921
4922 rem_probe_resp_ie_len = 0;
4923
4924 if (probe_rsp_ie_len[0] > 0)
4925 {
4926 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4927 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4928 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4929 probe_rsp_ie_len[0], NULL,
4930 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4931 {
4932 hddLog(LOGE,
4933 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004934 ret = -EINVAL;
4935 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 }
4937 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4938 }
4939
4940 if (probe_rsp_ie_len[1] > 0)
4941 {
4942 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4944 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4945 probe_rsp_ie_len[1], NULL,
4946 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4947 {
4948 hddLog(LOGE,
4949 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004950 ret = -EINVAL;
4951 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 }
4953 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4954 }
4955
4956 if (probe_rsp_ie_len[2] > 0)
4957 {
4958 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4959 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4960 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4961 probe_rsp_ie_len[2], NULL,
4962 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4963 {
4964 hddLog(LOGE,
4965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004966 ret = -EINVAL;
4967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 }
4969 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4970 }
4971
4972 if (probe_rsp_ie_len[1] == 0 )
4973 {
4974 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4975 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4976 eANI_BOOLEAN_FALSE) )
4977 {
4978 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004979 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 }
4981 }
4982
4983 if (probe_rsp_ie_len[2] == 0 )
4984 {
4985 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4986 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4987 eANI_BOOLEAN_FALSE) )
4988 {
4989 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004990 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 }
4992 }
4993
4994 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4995 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4996 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4997 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4998 == eHAL_STATUS_FAILURE)
4999 {
5000 hddLog(LOGE,
5001 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005002 ret = -EINVAL;
5003 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 }
5005 }
5006 else
5007 {
5008 // Reset WNI_CFG_PROBE_RSP Flags
5009 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5010
5011 hddLog(VOS_TRACE_LEVEL_INFO,
5012 "%s: No Probe Response IE received in set beacon",
5013 __func__);
5014 }
5015
5016 // Added for AssocResp IE
5017 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5018 {
5019 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5020 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5021 params->assocresp_ies_len, NULL,
5022 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5023 {
5024 hddLog(LOGE,
5025 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005026 ret = -EINVAL;
5027 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 }
5029
5030 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5031 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5032 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5033 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5034 == eHAL_STATUS_FAILURE)
5035 {
5036 hddLog(LOGE,
5037 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005038 ret = -EINVAL;
5039 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 }
5041 }
5042 else
5043 {
5044 hddLog(VOS_TRACE_LEVEL_INFO,
5045 "%s: No Assoc Response IE received in set beacon",
5046 __func__);
5047
5048 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5049 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5050 eANI_BOOLEAN_FALSE) )
5051 {
5052 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005053 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 }
5055 }
5056
Jeff Johnsone7245742012-09-05 17:12:55 -07005057done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305059 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005060}
Jeff Johnson295189b2012-06-20 16:38:30 -07005061
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305062/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 * FUNCTION: wlan_hdd_validate_operation_channel
5064 * called by wlan_hdd_cfg80211_start_bss() and
5065 * wlan_hdd_cfg80211_set_channel()
5066 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305067 * channel list.
5068 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005069VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005070{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305071
Jeff Johnson295189b2012-06-20 16:38:30 -07005072 v_U32_t num_ch = 0;
5073 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5074 u32 indx = 0;
5075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305076 v_U8_t fValidChannel = FALSE, count = 0;
5077 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5080
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305081 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305083 /* Validate the channel */
5084 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305086 if ( channel == rfChannels[count].channelNum )
5087 {
5088 fValidChannel = TRUE;
5089 break;
5090 }
5091 }
5092 if (fValidChannel != TRUE)
5093 {
5094 hddLog(VOS_TRACE_LEVEL_ERROR,
5095 "%s: Invalid Channel [%d]", __func__, channel);
5096 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 }
5098 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305099 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305101 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5102 valid_ch, &num_ch))
5103 {
5104 hddLog(VOS_TRACE_LEVEL_ERROR,
5105 "%s: failed to get valid channel list", __func__);
5106 return VOS_STATUS_E_FAILURE;
5107 }
5108 for (indx = 0; indx < num_ch; indx++)
5109 {
5110 if (channel == valid_ch[indx])
5111 {
5112 break;
5113 }
5114 }
5115
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305116 if (indx >= num_ch)
5117 {
5118 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5119 {
5120 eCsrBand band;
5121 unsigned int freq;
5122
5123 sme_GetFreqBand(hHal, &band);
5124
5125 if (eCSR_BAND_5G == band)
5126 {
5127#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5128 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5129 {
5130 freq = ieee80211_channel_to_frequency(channel,
5131 IEEE80211_BAND_2GHZ);
5132 }
5133 else
5134 {
5135 freq = ieee80211_channel_to_frequency(channel,
5136 IEEE80211_BAND_5GHZ);
5137 }
5138#else
5139 freq = ieee80211_channel_to_frequency(channel);
5140#endif
5141 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5142 return VOS_STATUS_SUCCESS;
5143 }
5144 }
5145
5146 hddLog(VOS_TRACE_LEVEL_ERROR,
5147 "%s: Invalid Channel [%d]", __func__, channel);
5148 return VOS_STATUS_E_FAILURE;
5149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305151
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153
Jeff Johnson295189b2012-06-20 16:38:30 -07005154}
5155
Viral Modi3a32cc52013-02-08 11:14:52 -08005156/**
5157 * FUNCTION: wlan_hdd_cfg80211_set_channel
5158 * This function is used to set the channel number
5159 */
5160static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5161 struct ieee80211_channel *chan,
5162 enum nl80211_channel_type channel_type
5163 )
5164{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305165 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005166 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005167 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005168 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305169 hdd_context_t *pHddCtx;
5170 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005171
5172 ENTER();
5173
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305174
Viral Modi3a32cc52013-02-08 11:14:52 -08005175 if( NULL == dev )
5176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005178 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005179 return -ENODEV;
5180 }
5181 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5184 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5185 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005186 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305187 "%s: device_mode = %s (%d) freq = %d", __func__,
5188 hdd_device_modetoString(pAdapter->device_mode),
5189 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305190
5191 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5192 status = wlan_hdd_validate_context(pHddCtx);
5193
5194 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005195 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5197 "%s: HDD context is not valid", __func__);
5198 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005199 }
5200
5201 /*
5202 * Do freq to chan conversion
5203 * TODO: for 11a
5204 */
5205
5206 channel = ieee80211_frequency_to_channel(freq);
5207
5208 /* Check freq range */
5209 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5210 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5211 {
5212 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005213 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005214 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5215 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5216 return -EINVAL;
5217 }
5218
5219 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5220
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305221 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5222 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005223 {
5224 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5225 {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005227 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5231 "%s: set channel to [%d] for device mode =%d",
5232 __func__, channel,pAdapter->device_mode);
5233 }
5234 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005235 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005236 )
5237 {
5238 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5239 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5241
5242 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5243 {
5244 /* Link is up then return cant set channel*/
5245 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005246 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005247 return -EINVAL;
5248 }
5249
5250 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5251 pHddStaCtx->conn_info.operationChannel = channel;
5252 pRoamProfile->ChannelInfo.ChannelList =
5253 &pHddStaCtx->conn_info.operationChannel;
5254 }
5255 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005256 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005257 )
5258 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305259 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5260 {
5261 if(VOS_STATUS_SUCCESS !=
5262 wlan_hdd_validate_operation_channel(pAdapter,channel))
5263 {
5264 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005265 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305266 return -EINVAL;
5267 }
5268 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5269 }
5270 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005271 {
5272 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5273
5274 /* If auto channel selection is configured as enable/ 1 then ignore
5275 channel set by supplicant
5276 */
5277 if ( cfg_param->apAutoChannelSelection )
5278 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305279 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5280 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005281 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305282 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5283 __func__, hdd_device_modetoString(pAdapter->device_mode),
5284 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005285 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305286 else
5287 {
5288 if(VOS_STATUS_SUCCESS !=
5289 wlan_hdd_validate_operation_channel(pAdapter,channel))
5290 {
5291 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005292 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305293 return -EINVAL;
5294 }
5295 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5296 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005297 }
5298 }
5299 else
5300 {
5301 hddLog(VOS_TRACE_LEVEL_FATAL,
5302 "%s: Invalid device mode failed to set valid channel", __func__);
5303 return -EINVAL;
5304 }
5305 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305306 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005307}
5308
Jeff Johnson295189b2012-06-20 16:38:30 -07005309#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5310static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5311 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005312#else
5313static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5314 struct cfg80211_beacon_data *params,
5315 const u8 *ssid, size_t ssid_len,
5316 enum nl80211_hidden_ssid hidden_ssid)
5317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005318{
5319 tsap_Config_t *pConfig;
5320 beacon_data_t *pBeacon = NULL;
5321 struct ieee80211_mgmt *pMgmt_frame;
5322 v_U8_t *pIe=NULL;
5323 v_U16_t capab_info;
5324 eCsrAuthType RSNAuthType;
5325 eCsrEncryptionType RSNEncryptType;
5326 eCsrEncryptionType mcRSNEncryptType;
5327 int status = VOS_STATUS_SUCCESS;
5328 tpWLAN_SAPEventCB pSapEventCallback;
5329 hdd_hostapd_state_t *pHostapdState;
5330 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5331 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305332 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305334 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005336 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005337 v_BOOL_t MFPCapable = VOS_FALSE;
5338 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305339 eHddDot11Mode sapDot11Mode =
5340 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005341
5342 ENTER();
5343
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305344 iniConfig = pHddCtx->cfg_ini;
5345
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5347
5348 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5349
5350 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5351
5352 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5353
5354 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5355
5356 //channel is already set in the set_channel Call back
5357 //pConfig->channel = pCommitConfig->channel;
5358
5359 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305360 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5362
5363 pConfig->dtim_period = pBeacon->dtim_period;
5364
Arif Hussain6d2a3322013-11-17 19:50:10 -08005365 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 pConfig->dtim_period);
5367
5368
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005369 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005370 {
5371 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305373 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5374 {
5375 tANI_BOOLEAN restartNeeded;
5376 pConfig->ieee80211d = 1;
5377 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5378 sme_setRegInfo(hHal, pConfig->countryCode);
5379 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5380 }
5381 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005383 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005384 pConfig->ieee80211d = 1;
5385 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5386 sme_setRegInfo(hHal, pConfig->countryCode);
5387 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005389 else
5390 {
5391 pConfig->ieee80211d = 0;
5392 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305393 /*
5394 * If auto channel is configured i.e. channel is 0,
5395 * so skip channel validation.
5396 */
5397 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5398 {
5399 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5400 {
5401 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005402 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305403 return -EINVAL;
5404 }
5405 }
5406 else
5407 {
5408 if(1 != pHddCtx->is_dynamic_channel_range_set)
5409 {
5410 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5411 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5412 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5413 }
5414 pHddCtx->is_dynamic_channel_range_set = 0;
5415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005416 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005417 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 {
5419 pConfig->ieee80211d = 0;
5420 }
5421 pConfig->authType = eSAP_AUTO_SWITCH;
5422
5423 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305424
5425 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5427
5428 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5429
5430 /*Set wps station to configured*/
5431 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5432
5433 if(pIe)
5434 {
5435 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5436 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005437 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 return -EINVAL;
5439 }
5440 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5441 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005442 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 /* Check 15 bit of WPS IE as it contain information for wps state
5444 * WPS state
5445 */
5446 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5447 {
5448 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5449 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5450 {
5451 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5452 }
5453 }
5454 }
5455 else
5456 {
5457 pConfig->wps_state = SAP_WPS_DISABLED;
5458 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305459 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005460
c_hpothufe599e92014-06-16 11:38:55 +05305461 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5462 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5463 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5464 eCSR_ENCRYPT_TYPE_NONE;
5465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 pConfig->RSNWPAReqIELength = 0;
5467 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305468 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 WLAN_EID_RSN);
5470 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5473 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5474 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 /* The actual processing may eventually be more extensive than
5476 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 * by the app.
5478 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305479 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5481 &RSNEncryptType,
5482 &mcRSNEncryptType,
5483 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005484 &MFPCapable,
5485 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 pConfig->pRSNWPAReqIE[1]+2,
5487 pConfig->pRSNWPAReqIE );
5488
5489 if( VOS_STATUS_SUCCESS == status )
5490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 /* Now copy over all the security attributes you have
5492 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 * */
5494 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5495 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5496 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5497 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305498 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005499 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5501 }
5502 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5505 pBeacon->tail, pBeacon->tail_len);
5506
5507 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5508 {
5509 if (pConfig->pRSNWPAReqIE)
5510 {
5511 /*Mixed mode WPA/WPA2*/
5512 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5513 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5514 }
5515 else
5516 {
5517 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5518 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5519 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5522 &RSNEncryptType,
5523 &mcRSNEncryptType,
5524 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005525 &MFPCapable,
5526 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 pConfig->pRSNWPAReqIE[1]+2,
5528 pConfig->pRSNWPAReqIE );
5529
5530 if( VOS_STATUS_SUCCESS == status )
5531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305532 /* Now copy over all the security attributes you have
5533 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 * */
5535 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5536 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5537 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5538 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305539 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005540 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5542 }
5543 }
5544 }
5545
Jeff Johnson4416a782013-03-25 14:17:50 -07005546 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5547 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5548 return -EINVAL;
5549 }
5550
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005553#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 if (params->ssid != NULL)
5555 {
5556 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5557 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5558 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5559 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5560 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005561#else
5562 if (ssid != NULL)
5563 {
5564 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5565 pConfig->SSIDinfo.ssid.length = ssid_len;
5566 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5567 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5568 }
5569#endif
5570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305573
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 /* default value */
5575 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5576 pConfig->num_accept_mac = 0;
5577 pConfig->num_deny_mac = 0;
5578
5579 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5580 pBeacon->tail, pBeacon->tail_len);
5581
5582 /* pIe for black list is following form:
5583 type : 1 byte
5584 length : 1 byte
5585 OUI : 4 bytes
5586 acl type : 1 byte
5587 no of mac addr in black list: 1 byte
5588 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589 */
5590 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 {
5592 pConfig->SapMacaddr_acl = pIe[6];
5593 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005594 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305596 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5597 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5599 for (i = 0; i < pConfig->num_deny_mac; i++)
5600 {
5601 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5602 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 }
5605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5606 pBeacon->tail, pBeacon->tail_len);
5607
5608 /* pIe for white list is following form:
5609 type : 1 byte
5610 length : 1 byte
5611 OUI : 4 bytes
5612 acl type : 1 byte
5613 no of mac addr in white list: 1 byte
5614 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 */
5616 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 {
5618 pConfig->SapMacaddr_acl = pIe[6];
5619 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005620 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305622 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5623 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5625 for (i = 0; i < pConfig->num_accept_mac; i++)
5626 {
5627 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5628 acl_entry++;
5629 }
5630 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305631
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5633
Jeff Johnsone7245742012-09-05 17:12:55 -07005634#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005635 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305636 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5637 * 11ac in .ini and 11ac is supported by both host and firmware.
5638 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5639 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005640 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5641 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305642 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5643 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5644 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5645 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5646 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005647 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305648 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005649 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305650 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005651
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305652 /* If ACS disable and selected channel <= 14
5653 * OR
5654 * ACS enabled and ACS operating band is choosen as 2.4
5655 * AND
5656 * VHT in 2.4G Disabled
5657 * THEN
5658 * Fallback to 11N mode
5659 */
5660 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5661 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305662 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305663 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005664 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305665 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5666 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005667 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5668 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005669 }
5670#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005672 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5673 {
5674 sme_SelectCBMode(hHal,
5675 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5676 pConfig->channel);
5677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 // ht_capab is not what the name conveys,this is used for protection bitmap
5679 pConfig->ht_capab =
5680 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5681
5682 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5683 {
5684 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5685 return -EINVAL;
5686 }
5687
5688 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305689 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5691 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692 pConfig->obssProtEnabled =
5693 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005694
Chet Lanctot8cecea22014-02-11 19:09:36 -08005695#ifdef WLAN_FEATURE_11W
5696 pConfig->mfpCapable = MFPCapable;
5697 pConfig->mfpRequired = MFPRequired;
5698 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5699 pConfig->mfpCapable, pConfig->mfpRequired);
5700#endif
5701
Arif Hussain6d2a3322013-11-17 19:50:10 -08005702 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005704 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5705 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5706 (int)pConfig->channel);
5707 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5708 pConfig->SapHw_mode, pConfig->privacy,
5709 pConfig->authType);
5710 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5711 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5712 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5713 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305715 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 {
5717 //Bss already started. just return.
5718 //TODO Probably it should update some beacon params.
5719 hddLog( LOGE, "Bss Already started...Ignore the request");
5720 EXIT();
5721 return 0;
5722 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723
Agarwal Ashish51325b52014-06-16 16:50:49 +05305724 if (vos_max_concurrent_connections_reached()) {
5725 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5726 return -EINVAL;
5727 }
5728
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 pConfig->persona = pHostapdAdapter->device_mode;
5730
5731 pSapEventCallback = hdd_hostapd_SAPEventCB;
5732 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5733 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5734 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005735 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 return -EINVAL;
5737 }
5738
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5741
5742 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305745 {
5746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005747 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005748 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 VOS_ASSERT(0);
5750 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05305753 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005754
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005755#ifdef WLAN_FEATURE_P2P_DEBUG
5756 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5757 {
5758 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5759 {
5760 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5761 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005762 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005763 }
5764 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5765 {
5766 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5767 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005768 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005769 }
5770 }
5771#endif
5772
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 pHostapdState->bCommit = TRUE;
5774 EXIT();
5775
5776 return 0;
5777}
5778
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005779#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305780static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5781 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 struct beacon_parameters *params)
5783{
5784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305785 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305786 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005787
5788 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305789
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305790 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5791 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5792 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305793 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5794 hdd_device_modetoString(pAdapter->device_mode),
5795 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005796
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305797 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5798 status = wlan_hdd_validate_context(pHddCtx);
5799
5800 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005801 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5803 "%s: HDD context is not valid", __func__);
5804 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005805 }
5806
Agarwal Ashish51325b52014-06-16 16:50:49 +05305807 if (vos_max_concurrent_connections_reached()) {
5808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5809 return -EINVAL;
5810 }
5811
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 )
5815 {
5816 beacon_data_t *old,*new;
5817
5818 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305821 {
5822 hddLog(VOS_TRACE_LEVEL_WARN,
5823 FL("already beacon info added to session(%d)"),
5824 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005827
5828 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5829
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305830 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 {
5832 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005833 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 return -EINVAL;
5835 }
5836
5837 pAdapter->sessionCtx.ap.beacon = new;
5838
5839 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5840 }
5841
5842 EXIT();
5843 return status;
5844}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845
5846static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 struct net_device *dev,
5848 struct beacon_parameters *params)
5849{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305850 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305851 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5852 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305853 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005854
5855 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305856 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5857 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5858 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5860 __func__, hdd_device_modetoString(pAdapter->device_mode),
5861 pAdapter->device_mode);
5862
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5864 status = wlan_hdd_validate_context(pHddCtx);
5865
5866 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005867 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5869 "%s: HDD context is not valid", __func__);
5870 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005871 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305872
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305875 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 {
5877 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305878
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305882 {
5883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5884 FL("session(%d) old and new heads points to NULL"),
5885 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005888
5889 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5890
5891 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005893 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 return -EINVAL;
5895 }
5896
5897 pAdapter->sessionCtx.ap.beacon = new;
5898
5899 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5900 }
5901
5902 EXIT();
5903 return status;
5904}
5905
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005906#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5907
5908#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005909static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5910 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005911#else
5912static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5913 struct net_device *dev)
5914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005915{
5916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005917 hdd_context_t *pHddCtx = NULL;
5918 hdd_scaninfo_t *pScanInfo = NULL;
5919 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305920 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305921 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005922
5923 ENTER();
5924
5925 if (NULL == pAdapter)
5926 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005928 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 return -ENODEV;
5930 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005931
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305932 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5933 TRACE_CODE_HDD_CFG80211_STOP_AP,
5934 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5936 status = wlan_hdd_validate_context(pHddCtx);
5937
5938 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005939 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5941 "%s: HDD context is not valid", __func__);
5942 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005943 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005944
5945 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5946 if (NULL == staAdapter)
5947 {
5948 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5949 if (NULL == staAdapter)
5950 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5952 "%s: HDD adapter context for STA/P2P-CLI is Null",
5953 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005954 }
5955 }
5956
5957 pScanInfo = &pHddCtx->scan_info;
5958
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305959 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5960 __func__, hdd_device_modetoString(pAdapter->device_mode),
5961 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005962
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305963 ret = wlan_hdd_scan_abort(pAdapter);
5964
Girish Gowli4bf7a632014-06-12 13:42:11 +05305965 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005966 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5968 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305969
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305970 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005971 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5973 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005974
Jeff Johnsone7245742012-09-05 17:12:55 -07005975 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305976 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005977 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305978 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005979 }
5980
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305981 hdd_hostapd_stop(dev);
5982
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 )
5986 {
5987 beacon_data_t *old;
5988
5989 old = pAdapter->sessionCtx.ap.beacon;
5990
5991 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305992 {
5993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5994 FL("session(%d) beacon data points to NULL"),
5995 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005998
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006000
6001 mutex_lock(&pHddCtx->sap_lock);
6002 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6003 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006004 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 {
6006 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6007
6008 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6009
6010 if (!VOS_IS_STATUS_SUCCESS(status))
6011 {
6012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006013 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306015 }
6016 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306018 /* BSS stopped, clear the active sessions for this device mode */
6019 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 }
6021 mutex_unlock(&pHddCtx->sap_lock);
6022
6023 if(status != VOS_STATUS_SUCCESS)
6024 {
6025 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006026 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 return -EINVAL;
6028 }
6029
Jeff Johnson4416a782013-03-25 14:17:50 -07006030 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6032 ==eHAL_STATUS_FAILURE)
6033 {
6034 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006035 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 }
6037
Jeff Johnson4416a782013-03-25 14:17:50 -07006038 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6040 eANI_BOOLEAN_FALSE) )
6041 {
6042 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006043 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 }
6045
6046 // Reset WNI_CFG_PROBE_RSP Flags
6047 wlan_hdd_reset_prob_rspies(pAdapter);
6048
6049 pAdapter->sessionCtx.ap.beacon = NULL;
6050 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006051#ifdef WLAN_FEATURE_P2P_DEBUG
6052 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6053 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6054 {
6055 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6056 "GO got removed");
6057 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6058 }
6059#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 }
6061 EXIT();
6062 return status;
6063}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006064
6065#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6066
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306067static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6068 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006069 struct cfg80211_ap_settings *params)
6070{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306071 hdd_adapter_t *pAdapter;
6072 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306073 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006074
6075 ENTER();
6076
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306077 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006078 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306080 "%s: Device is Null", __func__);
6081 return -ENODEV;
6082 }
6083
6084 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6085 if (NULL == pAdapter)
6086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306088 "%s: HDD adapter is Null", __func__);
6089 return -ENODEV;
6090 }
6091
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306092 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6093 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6094 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306095 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6096 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306098 "%s: HDD adapter magic is invalid", __func__);
6099 return -ENODEV;
6100 }
6101
6102 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306103 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306104
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306105 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306106 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6108 "%s: HDD context is not valid", __func__);
6109 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306110 }
6111
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306112 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6113 __func__, hdd_device_modetoString(pAdapter->device_mode),
6114 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306115
6116 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006117 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006118 )
6119 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306120 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006121
6122 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306123
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006124 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306125 {
6126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6127 FL("already beacon info added to session(%d)"),
6128 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006129 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306130 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006131
6132 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6133
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306134 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006135 {
6136 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306137 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006138 return -EINVAL;
6139 }
6140 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006142 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6143#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6144 params->channel, params->channel_type);
6145#else
6146 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6147#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006148#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006149 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6150 params->ssid_len, params->hidden_ssid);
6151 }
6152
6153 EXIT();
6154 return status;
6155}
6156
6157
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306158static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006159 struct net_device *dev,
6160 struct cfg80211_beacon_data *params)
6161{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306162 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306163 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306164 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006165
6166 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306167
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6169 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6170 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006172 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306173
6174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6175 status = wlan_hdd_validate_context(pHddCtx);
6176
6177 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006178 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6180 "%s: HDD context is not valid", __func__);
6181 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006182 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006183
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306184 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006185 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306186 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006187 {
6188 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306189
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006190 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306191
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006192 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306193 {
6194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6195 FL("session(%d) beacon data points to NULL"),
6196 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006197 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306198 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006199
6200 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6201
6202 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306203 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006204 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006205 return -EINVAL;
6206 }
6207
6208 pAdapter->sessionCtx.ap.beacon = new;
6209
6210 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6211 }
6212
6213 EXIT();
6214 return status;
6215}
6216
6217#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6218
Jeff Johnson295189b2012-06-20 16:38:30 -07006219
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306220static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 struct net_device *dev,
6222 struct bss_parameters *params)
6223{
6224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6225
6226 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306227
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306228 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6229 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6230 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306231 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6232 __func__, hdd_device_modetoString(pAdapter->device_mode),
6233 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006234
6235 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 {
6239 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6240 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306241 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 {
6243 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306244 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 }
6246
6247 EXIT();
6248 return 0;
6249}
6250
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306251static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6252 struct net_device *dev,
6253 struct bss_parameters *params)
6254{
6255 int ret;
6256
6257 vos_ssr_protect(__func__);
6258 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6259 vos_ssr_unprotect(__func__);
6260
6261 return ret;
6262}
Kiet Lam10841362013-11-01 11:36:50 +05306263/* FUNCTION: wlan_hdd_change_country_code_cd
6264* to wait for contry code completion
6265*/
6266void* wlan_hdd_change_country_code_cb(void *pAdapter)
6267{
6268 hdd_adapter_t *call_back_pAdapter = pAdapter;
6269 complete(&call_back_pAdapter->change_country_code);
6270 return NULL;
6271}
6272
Jeff Johnson295189b2012-06-20 16:38:30 -07006273/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306274 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6276 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306277int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 struct net_device *ndev,
6279 enum nl80211_iftype type,
6280 u32 *flags,
6281 struct vif_params *params
6282 )
6283{
6284 struct wireless_dev *wdev;
6285 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006286 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006287 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 tCsrRoamProfile *pRoamProfile = NULL;
6289 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306290 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 eMib_dot11DesiredBssType connectedBssType;
6292 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306293 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006294
6295 ENTER();
6296
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306297 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006298 {
6299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6300 "%s: Adapter context is null", __func__);
6301 return VOS_STATUS_E_FAILURE;
6302 }
6303
6304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6305 if (!pHddCtx)
6306 {
6307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6308 "%s: HDD context is null", __func__);
6309 return VOS_STATUS_E_FAILURE;
6310 }
6311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6313 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6314 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306315 status = wlan_hdd_validate_context(pHddCtx);
6316
6317 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6320 "%s: HDD context is not valid", __func__);
6321 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 }
6323
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306324 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6325 __func__, hdd_device_modetoString(pAdapter->device_mode),
6326 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006327
Agarwal Ashish51325b52014-06-16 16:50:49 +05306328 if (vos_max_concurrent_connections_reached()) {
6329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6330 return -EINVAL;
6331 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306332 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 wdev = ndev->ieee80211_ptr;
6334
6335#ifdef WLAN_BTAMP_FEATURE
6336 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6337 (NL80211_IFTYPE_ADHOC == type)||
6338 (NL80211_IFTYPE_AP == type)||
6339 (NL80211_IFTYPE_P2P_GO == type))
6340 {
6341 pHddCtx->isAmpAllowed = VOS_FALSE;
6342 // stop AMP traffic
6343 status = WLANBAP_StopAmp();
6344 if(VOS_STATUS_SUCCESS != status )
6345 {
6346 pHddCtx->isAmpAllowed = VOS_TRUE;
6347 hddLog(VOS_TRACE_LEVEL_FATAL,
6348 "%s: Failed to stop AMP", __func__);
6349 return -EINVAL;
6350 }
6351 }
6352#endif //WLAN_BTAMP_FEATURE
6353 /* Reset the current device mode bit mask*/
6354 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6355
6356 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006358 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 )
6360 {
6361 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006362 if (!pWextState)
6363 {
6364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6365 "%s: pWextState is null", __func__);
6366 return VOS_STATUS_E_FAILURE;
6367 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 pRoamProfile = &pWextState->roamProfile;
6369 LastBSSType = pRoamProfile->BSSType;
6370
6371 switch (type)
6372 {
6373 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 hddLog(VOS_TRACE_LEVEL_INFO,
6376 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6377 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006378#ifdef WLAN_FEATURE_11AC
6379 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6380 {
6381 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6382 }
6383#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306384 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006385 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006387 //Check for sub-string p2p to confirm its a p2p interface
6388 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306389 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006390 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6391 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6392 }
6393 else
6394 {
6395 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006397 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306398#ifdef FEATURE_WLAN_TDLS
6399 /* The open adapter for the p2p shall skip initializations in
6400 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6401 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6402 * tdls_init when the change_iface sets the device mode to
6403 * WLAN_HDD_P2P_CLIENT.
6404 */
6405
6406 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6407 {
6408 if (0 != wlan_hdd_tdls_init (pAdapter))
6409 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306410 hddLog(VOS_TRACE_LEVEL_ERROR,
6411 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306412 return -EINVAL;
6413 }
6414 }
6415#endif
6416
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 break;
6418 case NL80211_IFTYPE_ADHOC:
6419 hddLog(VOS_TRACE_LEVEL_INFO,
6420 "%s: setting interface Type to ADHOC", __func__);
6421 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6422 pRoamProfile->phyMode =
6423 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006424 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 wdev->iftype = type;
6426 break;
6427
6428 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
6431 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6432 "%s: setting interface Type to %s", __func__,
6433 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6434
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006435 //Cancel any remain on channel for GO mode
6436 if (NL80211_IFTYPE_P2P_GO == type)
6437 {
6438 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6439 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006440 if (NL80211_IFTYPE_AP == type)
6441 {
6442 /* As Loading WLAN Driver one interface being created for p2p device
6443 * address. This will take one HW STA and the max number of clients
6444 * that can connect to softAP will be reduced by one. so while changing
6445 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6446 * interface as it is not required in SoftAP mode.
6447 */
6448
6449 // Get P2P Adapter
6450 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6451
6452 if (pP2pAdapter)
6453 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306454 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006455 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6456 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6457 }
6458 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306459 //Disable IMPS & BMPS for SAP/GO
6460 if(VOS_STATUS_E_FAILURE ==
6461 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6462 {
6463 //Fail to Exit BMPS
6464 VOS_ASSERT(0);
6465 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306466#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006467
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306468 /* A Mutex Lock is introduced while changing the mode to
6469 * protect the concurrent access for the Adapters by TDLS
6470 * module.
6471 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306472 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306473#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306475 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 hdd_deinit_adapter( pHddCtx, pAdapter );
6477 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6479 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306480#ifdef FEATURE_WLAN_TDLS
6481 mutex_unlock(&pHddCtx->tdls_lock);
6482#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006483 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6484 (pConfig->apRandomBssidEnabled))
6485 {
6486 /* To meet Android requirements create a randomized
6487 MAC address of the form 02:1A:11:Fx:xx:xx */
6488 get_random_bytes(&ndev->dev_addr[3], 3);
6489 ndev->dev_addr[0] = 0x02;
6490 ndev->dev_addr[1] = 0x1A;
6491 ndev->dev_addr[2] = 0x11;
6492 ndev->dev_addr[3] |= 0xF0;
6493 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6494 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006495 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6496 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006497 }
6498
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 hdd_set_ap_ops( pAdapter->dev );
6500
Kiet Lam10841362013-11-01 11:36:50 +05306501 /* This is for only SAP mode where users can
6502 * control country through ini.
6503 * P2P GO follows station country code
6504 * acquired during the STA scanning. */
6505 if((NL80211_IFTYPE_AP == type) &&
6506 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6507 {
6508 int status = 0;
6509 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6510 "%s: setting country code from INI ", __func__);
6511 init_completion(&pAdapter->change_country_code);
6512 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6513 (void *)(tSmeChangeCountryCallback)
6514 wlan_hdd_change_country_code_cb,
6515 pConfig->apCntryCode, pAdapter,
6516 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306517 eSIR_FALSE,
6518 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306519 if (eHAL_STATUS_SUCCESS == status)
6520 {
6521 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306522 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306523 &pAdapter->change_country_code,
6524 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306525 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306526 {
6527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306528 FL("SME Timed out while setting country code %ld"),
6529 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006530
6531 if (pHddCtx->isLogpInProgress)
6532 {
6533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6534 "%s: LOGP in Progress. Ignore!!!", __func__);
6535 return -EAGAIN;
6536 }
Kiet Lam10841362013-11-01 11:36:50 +05306537 }
6538 }
6539 else
6540 {
6541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006542 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306543 return -EINVAL;
6544 }
6545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 status = hdd_init_ap_mode(pAdapter);
6547 if(status != VOS_STATUS_SUCCESS)
6548 {
6549 hddLog(VOS_TRACE_LEVEL_FATAL,
6550 "%s: Error initializing the ap mode", __func__);
6551 return -EINVAL;
6552 }
6553 hdd_set_conparam(1);
6554
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 /*interface type changed update in wiphy structure*/
6556 if(wdev)
6557 {
6558 wdev->iftype = type;
6559 pHddCtx->change_iface = type;
6560 }
6561 else
6562 {
6563 hddLog(VOS_TRACE_LEVEL_ERROR,
6564 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6565 return -EINVAL;
6566 }
6567 goto done;
6568 }
6569
6570 default:
6571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6572 __func__);
6573 return -EOPNOTSUPP;
6574 }
6575 }
6576 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 )
6579 {
6580 switch(type)
6581 {
6582 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306585#ifdef FEATURE_WLAN_TDLS
6586
6587 /* A Mutex Lock is introduced while changing the mode to
6588 * protect the concurrent access for the Adapters by TDLS
6589 * module.
6590 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306591 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306592#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306593 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006594 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006596 //Check for sub-string p2p to confirm its a p2p interface
6597 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006598 {
6599 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6600 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6601 }
6602 else
6603 {
6604 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 hdd_set_conparam(0);
6608 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6610 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306611#ifdef FEATURE_WLAN_TDLS
6612 mutex_unlock(&pHddCtx->tdls_lock);
6613#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306614 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 if( VOS_STATUS_SUCCESS != status )
6616 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006617 /* In case of JB, for P2P-GO, only change interface will be called,
6618 * This is the right place to enable back bmps_imps()
6619 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306620 if (pHddCtx->hdd_wlan_suspended)
6621 {
6622 hdd_set_pwrparams(pHddCtx);
6623 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006624 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 goto done;
6626 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6630 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 goto done;
6632 default:
6633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6634 __func__);
6635 return -EOPNOTSUPP;
6636
6637 }
6638
6639 }
6640 else
6641 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306642 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6643 __func__, hdd_device_modetoString(pAdapter->device_mode),
6644 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 return -EOPNOTSUPP;
6646 }
6647
6648
6649 if(pRoamProfile)
6650 {
6651 if ( LastBSSType != pRoamProfile->BSSType )
6652 {
6653 /*interface type changed update in wiphy structure*/
6654 wdev->iftype = type;
6655
6656 /*the BSS mode changed, We need to issue disconnect
6657 if connected or in IBSS disconnect state*/
6658 if ( hdd_connGetConnectedBssType(
6659 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6660 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6661 {
6662 /*need to issue a disconnect to CSR.*/
6663 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6664 if( eHAL_STATUS_SUCCESS ==
6665 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6666 pAdapter->sessionId,
6667 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6668 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306669 ret = wait_for_completion_interruptible_timeout(
6670 &pAdapter->disconnect_comp_var,
6671 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6672 if (ret <= 0)
6673 {
6674 hddLog(VOS_TRACE_LEVEL_ERROR,
6675 FL("wait on disconnect_comp_var failed %ld"), ret);
6676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 }
6678 }
6679 }
6680 }
6681
6682done:
6683 /*set bitmask based on updated value*/
6684 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006685
6686 /* Only STA mode support TM now
6687 * all other mode, TM feature should be disabled */
6688 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6689 (~VOS_STA & pHddCtx->concurrency_mode) )
6690 {
6691 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6692 }
6693
Jeff Johnson295189b2012-06-20 16:38:30 -07006694#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306695 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05306696 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 {
6698 //we are ok to do AMP
6699 pHddCtx->isAmpAllowed = VOS_TRUE;
6700 }
6701#endif //WLAN_BTAMP_FEATURE
6702 EXIT();
6703 return 0;
6704}
6705
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306706/*
6707 * FUNCTION: wlan_hdd_cfg80211_change_iface
6708 * wrapper function to protect the actual implementation from SSR.
6709 */
6710int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6711 struct net_device *ndev,
6712 enum nl80211_iftype type,
6713 u32 *flags,
6714 struct vif_params *params
6715 )
6716{
6717 int ret;
6718
6719 vos_ssr_protect(__func__);
6720 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6721 vos_ssr_unprotect(__func__);
6722
6723 return ret;
6724}
6725
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006726#ifdef FEATURE_WLAN_TDLS
6727static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6728 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6729{
6730 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6732 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006733 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306734 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306735 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006736
6737 ENTER();
6738
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306739 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006740 {
6741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6742 "Invalid arguments");
6743 return -EINVAL;
6744 }
Hoonki Lee27511902013-03-14 18:19:06 -07006745
6746 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6747 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6748 {
6749 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6750 "%s: TDLS mode is disabled OR not enabled in FW."
6751 MAC_ADDRESS_STR " Request declined.",
6752 __func__, MAC_ADDR_ARRAY(mac));
6753 return -ENOTSUPP;
6754 }
6755
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006756 if (pHddCtx->isLogpInProgress)
6757 {
6758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6759 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006760 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006761 return -EBUSY;
6762 }
6763
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306764 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006765
6766 if ( NULL == pTdlsPeer ) {
6767 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6768 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6769 __func__, MAC_ADDR_ARRAY(mac), update);
6770 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006771 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006772
6773 /* in add station, we accept existing valid staId if there is */
6774 if ((0 == update) &&
6775 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6776 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006777 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006778 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006779 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006780 " link_status %d. staId %d. add station ignored.",
6781 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6782 return 0;
6783 }
6784 /* in change station, we accept only when staId is valid */
6785 if ((1 == update) &&
6786 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6787 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6788 {
6789 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6790 "%s: " MAC_ADDRESS_STR
6791 " link status %d. staId %d. change station %s.",
6792 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6793 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6794 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006795 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006796
6797 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306798 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006799 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6801 "%s: " MAC_ADDRESS_STR
6802 " TDLS setup is ongoing. Request declined.",
6803 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006804 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006805 }
6806
6807 /* first to check if we reached to maximum supported TDLS peer.
6808 TODO: for now, return -EPERM looks working fine,
6809 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306810 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6811 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006812 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6814 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306815 " TDLS Max peer already connected. Request declined."
6816 " Num of peers (%d), Max allowed (%d).",
6817 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6818 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006819 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006820 }
6821 else
6822 {
6823 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306824 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006825 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006826 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6828 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6829 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006830 return -EPERM;
6831 }
6832 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006833 if (0 == update)
6834 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006835
Jeff Johnsond75fe012013-04-06 10:53:06 -07006836 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306837 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006838 {
6839 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6840 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006841 if(StaParams->htcap_present)
6842 {
6843 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6844 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6845 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6846 "ht_capa->extended_capabilities: %0x",
6847 StaParams->HTCap.extendedHtCapInfo);
6848 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006849 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6850 "params->capability: %0x",StaParams->capability);
6851 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006852 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006853 if(StaParams->vhtcap_present)
6854 {
6855 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6856 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6857 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6858 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6859 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006860 {
6861 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006863 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6864 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6865 "[%d]: %x ", i, StaParams->supported_rates[i]);
6866 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006867 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306868 else if ((1 == update) && (NULL == StaParams))
6869 {
6870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6871 "%s : update is true, but staParams is NULL. Error!", __func__);
6872 return -EPERM;
6873 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006874
6875 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6876
6877 if (!update)
6878 {
6879 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6880 pAdapter->sessionId, mac);
6881 }
6882 else
6883 {
6884 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6885 pAdapter->sessionId, mac, StaParams);
6886 }
6887
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306888 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006889 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6890
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306891 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006892 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306894 "%s: timeout waiting for tdls add station indication %ld",
6895 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006896 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006897 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306898
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006899 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6900 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006902 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006903 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006904 }
6905
6906 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006907
6908error:
6909 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6910 return -EPERM;
6911
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006912}
6913#endif
6914
Jeff Johnson295189b2012-06-20 16:38:30 -07006915static int wlan_hdd_change_station(struct wiphy *wiphy,
6916 struct net_device *dev,
6917 u8 *mac,
6918 struct station_parameters *params)
6919{
6920 VOS_STATUS status = VOS_STATUS_SUCCESS;
6921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306922 hdd_context_t *pHddCtx;
6923 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006925#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006926 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006927 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306928 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006929#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006930 ENTER();
6931
Gopichand Nakkala29149562013-05-10 21:43:41 +05306932 if ((NULL == pAdapter))
6933 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306935 "invalid adapter ");
6936 return -EINVAL;
6937 }
6938
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6940 TRACE_CODE_HDD_CHANGE_STATION,
6941 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6943 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6944
6945 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6946 {
6947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6948 "invalid HDD state or HDD station context");
6949 return -EINVAL;
6950 }
6951
6952 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006953 {
6954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6955 "%s:LOGP in Progress. Ignore!!!", __func__);
6956 return -EAGAIN;
6957 }
6958
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6960
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006961 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6962 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006964 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306966 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 WLANTL_STA_AUTHENTICATED);
6968
Gopichand Nakkala29149562013-05-10 21:43:41 +05306969 if (status != VOS_STATUS_SUCCESS)
6970 {
6971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6972 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6973 return -EINVAL;
6974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 }
6976 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006977 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6978 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306979#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006980 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6981 StaParams.capability = params->capability;
6982 StaParams.uapsd_queues = params->uapsd_queues;
6983 StaParams.max_sp = params->max_sp;
6984
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306985 /* Convert (first channel , number of channels) tuple to
6986 * the total list of channels. This goes with the assumption
6987 * that if the first channel is < 14, then the next channels
6988 * are an incremental of 1 else an incremental of 4 till the number
6989 * of channels.
6990 */
6991 if (0 != params->supported_channels_len) {
6992 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6993 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6994 {
6995 int wifi_chan_index;
6996 StaParams.supported_channels[j] = params->supported_channels[i];
6997 wifi_chan_index =
6998 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6999 no_of_channels = params->supported_channels[i+1];
7000 for(k=1; k <= no_of_channels; k++)
7001 {
7002 StaParams.supported_channels[j+1] =
7003 StaParams.supported_channels[j] + wifi_chan_index;
7004 j+=1;
7005 }
7006 }
7007 StaParams.supported_channels_len = j;
7008 }
7009 vos_mem_copy(StaParams.supported_oper_classes,
7010 params->supported_oper_classes,
7011 params->supported_oper_classes_len);
7012 StaParams.supported_oper_classes_len =
7013 params->supported_oper_classes_len;
7014
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007015 if (0 != params->ext_capab_len)
7016 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7017 sizeof(StaParams.extn_capability));
7018
7019 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007020 {
7021 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007022 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007023 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007024
7025 StaParams.supported_rates_len = params->supported_rates_len;
7026
7027 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7028 * The supported_rates array , for all the structures propogating till Add Sta
7029 * to the firmware has to be modified , if the supplicant (ieee80211) is
7030 * modified to send more rates.
7031 */
7032
7033 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7034 */
7035 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7036 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7037
7038 if (0 != StaParams.supported_rates_len) {
7039 int i = 0;
7040 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7041 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007043 "Supported Rates with Length %d", StaParams.supported_rates_len);
7044 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007046 "[%d]: %0x", i, StaParams.supported_rates[i]);
7047 }
7048
7049 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007050 {
7051 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007052 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007053 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007054
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007055 if (0 != params->ext_capab_len ) {
7056 /*Define A Macro : TODO Sunil*/
7057 if ((1<<4) & StaParams.extn_capability[3]) {
7058 isBufSta = 1;
7059 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307060 /* TDLS Channel Switching Support */
7061 if ((1<<6) & StaParams.extn_capability[3]) {
7062 isOffChannelSupported = 1;
7063 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007064 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307065 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7066 &StaParams, isBufSta,
7067 isOffChannelSupported);
7068
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307069 if (VOS_STATUS_SUCCESS != status) {
7070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7071 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7072 return -EINVAL;
7073 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007074 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7075
7076 if (VOS_STATUS_SUCCESS != status) {
7077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7078 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7079 return -EINVAL;
7080 }
7081 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007082#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307083 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007084 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 return status;
7086}
7087
7088/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307089 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 * This function is used to initialize the key information
7091 */
7092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307093static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 struct net_device *ndev,
7095 u8 key_index, bool pairwise,
7096 const u8 *mac_addr,
7097 struct key_params *params
7098 )
7099#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307100static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 struct net_device *ndev,
7102 u8 key_index, const u8 *mac_addr,
7103 struct key_params *params
7104 )
7105#endif
7106{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 tCsrRoamSetKey setKey;
7109 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307110 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007111 v_U32_t roamId= 0xFF;
7112 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 hdd_hostapd_state_t *pHostapdState;
7114 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007115 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307116 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007117
7118 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307119
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7121 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7122 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7124 status = wlan_hdd_validate_context(pHddCtx);
7125
7126 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7129 "%s: HDD context is not valid", __func__);
7130 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007131 }
7132
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7134 __func__, hdd_device_modetoString(pAdapter->device_mode),
7135 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007136
7137 if (CSR_MAX_NUM_KEY <= key_index)
7138 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 key_index);
7141
7142 return -EINVAL;
7143 }
7144
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007145 if (CSR_MAX_KEY_LEN < params->key_len)
7146 {
7147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7148 params->key_len);
7149
7150 return -EINVAL;
7151 }
7152
7153 hddLog(VOS_TRACE_LEVEL_INFO,
7154 "%s: called with key index = %d & key length %d",
7155 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007156
7157 /*extract key idx, key len and key*/
7158 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7159 setKey.keyId = key_index;
7160 setKey.keyLength = params->key_len;
7161 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007163 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 {
7165 case WLAN_CIPHER_SUITE_WEP40:
7166 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7167 break;
7168
7169 case WLAN_CIPHER_SUITE_WEP104:
7170 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7171 break;
7172
7173 case WLAN_CIPHER_SUITE_TKIP:
7174 {
7175 u8 *pKey = &setKey.Key[0];
7176 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7177
7178 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7179
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007180 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007181
7182 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007183 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 |--------------|----------|----------|
7185 <---16bytes---><--8bytes--><--8bytes-->
7186
7187 */
7188 /*Sme expects the 32 bytes key to be in the below order
7189
7190 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007191 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 |--------------|----------|----------|
7193 <---16bytes---><--8bytes--><--8bytes-->
7194 */
7195 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007196 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007199 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007200
7201 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007202 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007203
7204
7205 break;
7206 }
7207
7208 case WLAN_CIPHER_SUITE_CCMP:
7209 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7210 break;
7211
7212#ifdef FEATURE_WLAN_WAPI
7213 case WLAN_CIPHER_SUITE_SMS4:
7214 {
7215 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7216 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7217 params->key, params->key_len);
7218 return 0;
7219 }
7220#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007221
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007222#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 case WLAN_CIPHER_SUITE_KRK:
7224 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7225 break;
7226#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007227
7228#ifdef WLAN_FEATURE_11W
7229 case WLAN_CIPHER_SUITE_AES_CMAC:
7230 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007231 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007232#endif
7233
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 __func__, params->cipher);
7237 return -EOPNOTSUPP;
7238 }
7239
7240 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7241 __func__, setKey.encType);
7242
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007243 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7245 (!pairwise)
7246#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007247 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007248#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007249 )
7250 {
7251 /* set group key*/
7252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7253 "%s- %d: setting Broadcast key",
7254 __func__, __LINE__);
7255 setKey.keyDirection = eSIR_RX_ONLY;
7256 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7257 }
7258 else
7259 {
7260 /* set pairwise key*/
7261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7262 "%s- %d: setting pairwise key",
7263 __func__, __LINE__);
7264 setKey.keyDirection = eSIR_TX_RX;
7265 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7266 }
7267 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7268 {
7269 setKey.keyDirection = eSIR_TX_RX;
7270 /*Set the group key*/
7271 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7272 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007273
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007274 if ( 0 != status )
7275 {
7276 hddLog(VOS_TRACE_LEVEL_ERROR,
7277 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7278 return -EINVAL;
7279 }
7280 /*Save the keys here and call sme_RoamSetKey for setting
7281 the PTK after peer joins the IBSS network*/
7282 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7283 &setKey, sizeof(tCsrRoamSetKey));
7284 return status;
7285 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307286 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7287 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7288 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007290 if( pHostapdState->bssState == BSS_START )
7291 {
c_hpothu7c55da62014-01-23 18:34:02 +05307292 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7293 vos_status = wlan_hdd_check_ula_done(pAdapter);
7294
7295 if ( vos_status != VOS_STATUS_SUCCESS )
7296 {
7297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7298 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7299 __LINE__, vos_status );
7300
7301 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7302
7303 return -EINVAL;
7304 }
7305
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7307
7308 if ( status != eHAL_STATUS_SUCCESS )
7309 {
7310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7311 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7312 __LINE__, status );
7313 }
7314 }
7315
7316 /* Saving WEP keys */
7317 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7318 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7319 {
7320 //Save the wep key in ap context. Issue setkey after the BSS is started.
7321 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7322 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7323 }
7324 else
7325 {
7326 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007327 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7329 }
7330 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007331 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7332 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 {
7334 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7335 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7336
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7338 if (!pairwise)
7339#else
7340 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7341#endif
7342 {
7343 /* set group key*/
7344 if (pHddStaCtx->roam_info.deferKeyComplete)
7345 {
7346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7347 "%s- %d: Perform Set key Complete",
7348 __func__, __LINE__);
7349 hdd_PerformRoamSetKeyComplete(pAdapter);
7350 }
7351 }
7352
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7354
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007355 pWextState->roamProfile.Keys.defaultIndex = key_index;
7356
7357
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007358 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 params->key, params->key_len);
7360
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307361
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7363
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307364 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307366 __func__, setKey.peerMac[0], setKey.peerMac[1],
7367 setKey.peerMac[2], setKey.peerMac[3],
7368 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 setKey.keyDirection);
7370
7371 vos_status = wlan_hdd_check_ula_done(pAdapter);
7372
7373 if ( vos_status != VOS_STATUS_SUCCESS )
7374 {
7375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7376 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7377 __LINE__, vos_status );
7378
7379 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7380
7381 return -EINVAL;
7382
7383 }
7384
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007385#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307386 /* The supplicant may attempt to set the PTK once pre-authentication
7387 is done. Save the key in the UMAC and include it in the ADD BSS
7388 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007389 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307390 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007391 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307392 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7393 "%s: Update PreAuth Key success", __func__);
7394 return 0;
7395 }
7396 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7397 {
7398 hddLog(VOS_TRACE_LEVEL_ERROR,
7399 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307400 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007401 }
7402#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007403
7404 /* issue set key request to SME*/
7405 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7406 pAdapter->sessionId, &setKey, &roamId );
7407
7408 if ( 0 != status )
7409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307410 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7412 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7413 return -EINVAL;
7414 }
7415
7416
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307417 /* in case of IBSS as there was no information available about WEP keys during
7418 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007419 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307420 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7421 !( ( IW_AUTH_KEY_MGMT_802_1X
7422 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7424 )
7425 &&
7426 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7427 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7428 )
7429 )
7430 {
7431 setKey.keyDirection = eSIR_RX_ONLY;
7432 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307434 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 __func__, setKey.peerMac[0], setKey.peerMac[1],
7437 setKey.peerMac[2], setKey.peerMac[3],
7438 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 setKey.keyDirection);
7440
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307441 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 pAdapter->sessionId, &setKey, &roamId );
7443
7444 if ( 0 != status )
7445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307446 hddLog(VOS_TRACE_LEVEL_ERROR,
7447 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 __func__, status);
7449 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7450 return -EINVAL;
7451 }
7452 }
7453 }
7454
7455 return 0;
7456}
7457
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7459static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7460 struct net_device *ndev,
7461 u8 key_index, bool pairwise,
7462 const u8 *mac_addr,
7463 struct key_params *params
7464 )
7465#else
7466static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7467 struct net_device *ndev,
7468 u8 key_index, const u8 *mac_addr,
7469 struct key_params *params
7470 )
7471#endif
7472{
7473 int ret;
7474 vos_ssr_protect(__func__);
7475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7476 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7477 mac_addr, params);
7478#else
7479 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7480 params);
7481#endif
7482 vos_ssr_unprotect(__func__);
7483
7484 return ret;
7485}
7486
Jeff Johnson295189b2012-06-20 16:38:30 -07007487/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307488 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 * This function is used to get the key information
7490 */
7491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307492static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307493 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307495 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 const u8 *mac_addr, void *cookie,
7497 void (*callback)(void *cookie, struct key_params*)
7498 )
7499#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307500static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307501 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 struct net_device *ndev,
7503 u8 key_index, const u8 *mac_addr, void *cookie,
7504 void (*callback)(void *cookie, struct key_params*)
7505 )
7506#endif
7507{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307508 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307509 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7510 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 struct key_params params;
7512
7513 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307514
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7516 __func__, hdd_device_modetoString(pAdapter->device_mode),
7517 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307518
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 memset(&params, 0, sizeof(params));
7520
7521 if (CSR_MAX_NUM_KEY <= key_index)
7522 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007526
7527 switch(pRoamProfile->EncryptionType.encryptionType[0])
7528 {
7529 case eCSR_ENCRYPT_TYPE_NONE:
7530 params.cipher = IW_AUTH_CIPHER_NONE;
7531 break;
7532
7533 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7534 case eCSR_ENCRYPT_TYPE_WEP40:
7535 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7536 break;
7537
7538 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7539 case eCSR_ENCRYPT_TYPE_WEP104:
7540 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7541 break;
7542
7543 case eCSR_ENCRYPT_TYPE_TKIP:
7544 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7545 break;
7546
7547 case eCSR_ENCRYPT_TYPE_AES:
7548 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7549 break;
7550
7551 default:
7552 params.cipher = IW_AUTH_CIPHER_NONE;
7553 break;
7554 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307555
c_hpothuaaf19692014-05-17 17:01:48 +05307556 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7557 TRACE_CODE_HDD_CFG80211_GET_KEY,
7558 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307559
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7561 params.seq_len = 0;
7562 params.seq = NULL;
7563 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7564 callback(cookie, &params);
7565 return 0;
7566}
7567
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307568#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7569static int wlan_hdd_cfg80211_get_key(
7570 struct wiphy *wiphy,
7571 struct net_device *ndev,
7572 u8 key_index, bool pairwise,
7573 const u8 *mac_addr, void *cookie,
7574 void (*callback)(void *cookie, struct key_params*)
7575 )
7576#else
7577static int wlan_hdd_cfg80211_get_key(
7578 struct wiphy *wiphy,
7579 struct net_device *ndev,
7580 u8 key_index, const u8 *mac_addr, void *cookie,
7581 void (*callback)(void *cookie, struct key_params*)
7582 )
7583#endif
7584{
7585 int ret;
7586
7587 vos_ssr_protect(__func__);
7588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7589 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7590 mac_addr, cookie, callback);
7591#else
7592 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7593 callback);
7594#endif
7595 vos_ssr_unprotect(__func__);
7596
7597 return ret;
7598}
7599
Jeff Johnson295189b2012-06-20 16:38:30 -07007600/*
7601 * FUNCTION: wlan_hdd_cfg80211_del_key
7602 * This function is used to delete the key information
7603 */
7604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307605static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007606 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307607 u8 key_index,
7608 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 const u8 *mac_addr
7610 )
7611#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307612static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007613 struct net_device *ndev,
7614 u8 key_index,
7615 const u8 *mac_addr
7616 )
7617#endif
7618{
7619 int status = 0;
7620
7621 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307622 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 //it is observed that this is invalidating peer
7624 //key index whenever re-key is done. This is affecting data link.
7625 //It should be ok to ignore del_key.
7626#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7628 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7630 tCsrRoamSetKey setKey;
7631 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307632
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 ENTER();
7634
7635 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7636 __func__,pAdapter->device_mode);
7637
7638 if (CSR_MAX_NUM_KEY <= key_index)
7639 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 key_index);
7642
7643 return -EINVAL;
7644 }
7645
7646 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7647 setKey.keyId = key_index;
7648
7649 if (mac_addr)
7650 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7651 else
7652 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7653
7654 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7655
7656 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307658 )
7659 {
7660
7661 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7663 if( pHostapdState->bssState == BSS_START)
7664 {
7665 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307666
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 if ( status != eHAL_STATUS_SUCCESS )
7668 {
7669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7670 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7671 __LINE__, status );
7672 }
7673 }
7674 }
7675 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307676 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007677 )
7678 {
7679 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7680
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307681 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7682
7683 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307685 __func__, setKey.peerMac[0], setKey.peerMac[1],
7686 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307688 if(pAdapter->sessionCtx.station.conn_info.connState ==
7689 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307691 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007692 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307693
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 if ( 0 != status )
7695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307696 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 "%s: sme_RoamSetKey failure, returned %d",
7698 __func__, status);
7699 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7700 return -EINVAL;
7701 }
7702 }
7703 }
7704#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007705 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 return status;
7707}
7708
7709/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307710 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007711 * This function is used to set the default tx key index
7712 */
7713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307714static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 struct net_device *ndev,
7716 u8 key_index,
7717 bool unicast, bool multicast)
7718#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307719static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 struct net_device *ndev,
7721 u8 key_index)
7722#endif
7723{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307725 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307726 hdd_wext_state_t *pWextState;
7727 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307728 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
7730 ENTER();
7731
Gopichand Nakkala29149562013-05-10 21:43:41 +05307732 if ((NULL == pAdapter))
7733 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307735 "invalid adapter");
7736 return -EINVAL;
7737 }
7738
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307739 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7740 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7741 pAdapter->sessionId, key_index));
7742
Gopichand Nakkala29149562013-05-10 21:43:41 +05307743 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7744 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7745
7746 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7747 {
7748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7749 "invalid Wext state or HDD context");
7750 return -EINVAL;
7751 }
7752
Arif Hussain6d2a3322013-11-17 19:50:10 -08007753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307755
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 if (CSR_MAX_NUM_KEY <= key_index)
7757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 key_index);
7760
7761 return -EINVAL;
7762 }
7763
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307764 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7765 status = wlan_hdd_validate_context(pHddCtx);
7766
7767 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007768 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7770 "%s: HDD context is not valid", __func__);
7771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007772 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307773
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307776 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307778 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007779 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307780 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007781 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307783 {
7784 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007785 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307786
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 tCsrRoamSetKey setKey;
7788 v_U32_t roamId= 0xFF;
7789 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307790
7791 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307793
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 Keys->defaultIndex = (u8)key_index;
7795 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7796 setKey.keyId = key_index;
7797 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307798
7799 vos_mem_copy(&setKey.Key[0],
7800 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802
Gopichand Nakkala29149562013-05-10 21:43:41 +05307803 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307804
7805 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 &pHddStaCtx->conn_info.bssId[0],
7807 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307808
Gopichand Nakkala29149562013-05-10 21:43:41 +05307809 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7810 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7811 eCSR_ENCRYPT_TYPE_WEP104)
7812 {
7813 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7814 even though ap is configured for WEP-40 encryption. In this canse the key length
7815 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7816 type(104) and switching encryption type to 40*/
7817 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7818 eCSR_ENCRYPT_TYPE_WEP40;
7819 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7820 eCSR_ENCRYPT_TYPE_WEP40;
7821 }
7822
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307823 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307825
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307827 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007828 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 if ( 0 != status )
7831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307832 hddLog(VOS_TRACE_LEVEL_ERROR,
7833 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 status);
7835 return -EINVAL;
7836 }
7837 }
7838 }
7839
7840 /* In SoftAp mode setting key direction for default mode */
7841 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7842 {
7843 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7844 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7845 (eCSR_ENCRYPT_TYPE_AES !=
7846 pWextState->roamProfile.EncryptionType.encryptionType[0])
7847 )
7848 {
7849 /* Saving key direction for default key index to TX default */
7850 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7851 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7852 }
7853 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307854
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 return status;
7856}
7857
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7859static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7860 struct net_device *ndev,
7861 u8 key_index,
7862 bool unicast, bool multicast)
7863#else
7864static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7865 struct net_device *ndev,
7866 u8 key_index)
7867#endif
7868{
7869 int ret;
7870 vos_ssr_protect(__func__);
7871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7872 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7873 multicast);
7874#else
7875 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7876#endif
7877 vos_ssr_unprotect(__func__);
7878
7879 return ret;
7880}
7881
Jeff Johnson295189b2012-06-20 16:38:30 -07007882/*
7883 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7884 * This function is used to inform the BSS details to nl80211 interface.
7885 */
7886static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7887 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7888{
7889 struct net_device *dev = pAdapter->dev;
7890 struct wireless_dev *wdev = dev->ieee80211_ptr;
7891 struct wiphy *wiphy = wdev->wiphy;
7892 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7893 int chan_no;
7894 int ie_length;
7895 const char *ie;
7896 unsigned int freq;
7897 struct ieee80211_channel *chan;
7898 int rssi = 0;
7899 struct cfg80211_bss *bss = NULL;
7900
7901 ENTER();
7902
7903 if( NULL == pBssDesc )
7904 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007905 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 return bss;
7907 }
7908
7909 chan_no = pBssDesc->channelId;
7910 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7911 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7912
7913 if( NULL == ie )
7914 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007915 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 return bss;
7917 }
7918
7919#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7920 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7921 {
7922 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7923 }
7924 else
7925 {
7926 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7927 }
7928#else
7929 freq = ieee80211_channel_to_frequency(chan_no);
7930#endif
7931
7932 chan = __ieee80211_get_channel(wiphy, freq);
7933
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307934 if (!chan) {
7935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7936 return NULL;
7937 }
7938
Abhishek Singhaee43942014-06-16 18:55:47 +05307939 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007940
Abhishek Singhaee43942014-06-16 18:55:47 +05307941 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307942 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 pBssDesc->capabilityInfo,
7944 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307945 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007946}
7947
7948
7949
7950/*
7951 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7952 * This function is used to inform the BSS details to nl80211 interface.
7953 */
7954struct cfg80211_bss*
7955wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7956 tSirBssDescription *bss_desc
7957 )
7958{
7959 /*
7960 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7961 already exists in bss data base of cfg80211 for that particular BSS ID.
7962 Using cfg80211_inform_bss_frame to update the bss entry instead of
7963 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7964 now there is no possibility to get the mgmt(probe response) frame from PE,
7965 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7966 cfg80211_inform_bss_frame.
7967 */
7968 struct net_device *dev = pAdapter->dev;
7969 struct wireless_dev *wdev = dev->ieee80211_ptr;
7970 struct wiphy *wiphy = wdev->wiphy;
7971 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007972#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7973 qcom_ie_age *qie_age = NULL;
7974 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7975#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 const char *ie =
7979 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7980 unsigned int freq;
7981 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307982 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 struct cfg80211_bss *bss_status = NULL;
7984 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7985 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007986 hdd_context_t *pHddCtx;
7987 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007988#ifdef WLAN_OPEN_SOURCE
7989 struct timespec ts;
7990#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007991
Wilson Yangf80a0542013-10-07 13:02:37 -07007992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7993 status = wlan_hdd_validate_context(pHddCtx);
7994
7995 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307996 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007997 {
7998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7999 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8000 return NULL;
8001 }
8002
8003
8004 if (0 != status)
8005 {
8006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8007 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008008 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008009 }
8010
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308011 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008012 if (!mgmt)
8013 {
8014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8015 "%s: memory allocation failed ", __func__);
8016 return NULL;
8017 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008018
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008020
8021#ifdef WLAN_OPEN_SOURCE
8022 /* Android does not want the timestamp from the frame.
8023 Instead it wants a monotonic increasing value */
8024 get_monotonic_boottime(&ts);
8025 mgmt->u.probe_resp.timestamp =
8026 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8027#else
8028 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8030 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008031
8032#endif
8033
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8035 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008036
8037#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8038 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8039 /* Assuming this is the last IE, copy at the end */
8040 ie_length -=sizeof(qcom_ie_age);
8041 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8042 qie_age->element_id = QCOM_VENDOR_IE_ID;
8043 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8044 qie_age->oui_1 = QCOM_OUI1;
8045 qie_age->oui_2 = QCOM_OUI2;
8046 qie_age->oui_3 = QCOM_OUI3;
8047 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8048 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8049#endif
8050
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308052 if (bss_desc->fProbeRsp)
8053 {
8054 mgmt->frame_control |=
8055 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8056 }
8057 else
8058 {
8059 mgmt->frame_control |=
8060 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8061 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008062
8063#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8066 {
8067 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308069 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8071
8072 {
8073 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8074 }
8075 else
8076 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8078 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 kfree(mgmt);
8080 return NULL;
8081 }
8082#else
8083 freq = ieee80211_channel_to_frequency(chan_no);
8084#endif
8085 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008086 /*when the band is changed on the fly using the GUI, three things are done
8087 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
8088 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8089 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8090 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8091 * and discards the channels correponding to previous band and calls back with zero bss results.
8092 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
8093 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8094 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8095 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8096 * So drop the bss and continue to next bss.
8097 */
8098 if(chan == NULL)
8099 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008101 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008102 return NULL;
8103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308105 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 * */
8107 if (( eConnectionState_Associated ==
8108 pAdapter->sessionCtx.station.conn_info.connState ) &&
8109 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8110 pAdapter->sessionCtx.station.conn_info.bssId,
8111 WNI_CFG_BSSID_LEN)))
8112 {
8113 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8114 rssi = (pAdapter->rssi * 100);
8115 }
8116 else
8117 {
8118 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8119 }
8120
Nirav Shah20ac06f2013-12-12 18:14:06 +05308121 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8122 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8123 chan->center_freq, (int)(rssi/100));
8124
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8126 frame_len, rssi, GFP_KERNEL);
8127 kfree(mgmt);
8128 return bss_status;
8129}
8130
8131/*
8132 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8133 * This function is used to update the BSS data base of CFG8011
8134 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308135struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 tCsrRoamInfo *pRoamInfo
8137 )
8138{
8139 tCsrRoamConnectedProfile roamProfile;
8140 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8141 struct cfg80211_bss *bss = NULL;
8142
8143 ENTER();
8144
8145 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8146 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8147
8148 if (NULL != roamProfile.pBssDesc)
8149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 &roamProfile);
8152
8153 if (NULL == bss)
8154 {
8155 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8156 __func__);
8157 }
8158
8159 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8160 }
8161 else
8162 {
8163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8164 __func__);
8165 }
8166 return bss;
8167}
8168
8169/*
8170 * FUNCTION: wlan_hdd_cfg80211_update_bss
8171 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308172static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8173 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308176 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008177 tCsrScanResultInfo *pScanResult;
8178 eHalStatus status = 0;
8179 tScanResultHandle pResult;
8180 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008181 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008182
8183 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308184
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8186 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8187 NO_SESSION, pAdapter->sessionId));
8188
Wilson Yangf80a0542013-10-07 13:02:37 -07008189 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8190
8191 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8194 "%s:LOGP in Progress. Ignore!!!",__func__);
8195 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 }
8197
Wilson Yangf80a0542013-10-07 13:02:37 -07008198
8199 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308200 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008201 {
8202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8203 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8204 return VOS_STATUS_E_PERM;
8205 }
8206
8207
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 /*
8209 * start getting scan results and populate cgf80211 BSS database
8210 */
8211 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8212
8213 /* no scan results */
8214 if (NULL == pResult)
8215 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8217 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 return status;
8219 }
8220
8221 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8222
8223 while (pScanResult)
8224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308225 /*
8226 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8227 * entry already exists in bss data base of cfg80211 for that
8228 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8229 * bss entry instead of cfg80211_inform_bss, But this call expects
8230 * mgmt packet as input. As of now there is no possibility to get
8231 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 * ieee80211_mgmt(probe response) and passing to c
8233 * fg80211_inform_bss_frame.
8234 * */
8235
8236 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8237 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238
Jeff Johnson295189b2012-06-20 16:38:30 -07008239
8240 if (NULL == bss_status)
8241 {
8242 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008243 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 }
8245 else
8246 {
Yue Maf49ba872013-08-19 12:04:25 -07008247 cfg80211_put_bss(
8248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8249 wiphy,
8250#endif
8251 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 }
8253
8254 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8255 }
8256
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308257 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008258
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308259 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008260}
8261
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008262void
8263hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8264{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308265 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008266 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008267} /****** end hddPrintMacAddr() ******/
8268
8269void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008270hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008273 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008274 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8275 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8276 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008277} /****** end hddPrintPmkId() ******/
8278
8279//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8280//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8281
8282//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8283//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8284
8285#define dump_bssid(bssid) \
8286 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008287 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8288 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008289 }
8290
8291#define dump_pmkid(pMac, pmkid) \
8292 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008293 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8294 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008295 }
8296
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008297#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008298/*
8299 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8300 * This function is used to notify the supplicant of a new PMKSA candidate.
8301 */
8302int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308303 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008304 int index, bool preauth )
8305{
Jeff Johnsone7245742012-09-05 17:12:55 -07008306#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008307 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008308 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008309
8310 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008311 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008312
8313 if( NULL == pRoamInfo )
8314 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008315 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008316 return -EINVAL;
8317 }
8318
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008319 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8320 {
8321 dump_bssid(pRoamInfo->bssid);
8322 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008323 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008324 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008325#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308326 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008327}
8328#endif //FEATURE_WLAN_LFR
8329
Yue Maef608272013-04-08 23:09:17 -07008330#ifdef FEATURE_WLAN_LFR_METRICS
8331/*
8332 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8333 * 802.11r/LFR metrics reporting function to report preauth initiation
8334 *
8335 */
8336#define MAX_LFR_METRICS_EVENT_LENGTH 100
8337VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8338 tCsrRoamInfo *pRoamInfo)
8339{
8340 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8341 union iwreq_data wrqu;
8342
8343 ENTER();
8344
8345 if (NULL == pAdapter)
8346 {
8347 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8348 return VOS_STATUS_E_FAILURE;
8349 }
8350
8351 /* create the event */
8352 memset(&wrqu, 0, sizeof(wrqu));
8353 memset(metrics_notification, 0, sizeof(metrics_notification));
8354
8355 wrqu.data.pointer = metrics_notification;
8356 wrqu.data.length = scnprintf(metrics_notification,
8357 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8358 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8359
8360 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8361
8362 EXIT();
8363
8364 return VOS_STATUS_SUCCESS;
8365}
8366
8367/*
8368 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8369 * 802.11r/LFR metrics reporting function to report preauth completion
8370 * or failure
8371 */
8372VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8373 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8374{
8375 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8376 union iwreq_data wrqu;
8377
8378 ENTER();
8379
8380 if (NULL == pAdapter)
8381 {
8382 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8383 return VOS_STATUS_E_FAILURE;
8384 }
8385
8386 /* create the event */
8387 memset(&wrqu, 0, sizeof(wrqu));
8388 memset(metrics_notification, 0, sizeof(metrics_notification));
8389
8390 scnprintf(metrics_notification, sizeof(metrics_notification),
8391 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8392 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8393
8394 if (1 == preauth_status)
8395 strncat(metrics_notification, " TRUE", 5);
8396 else
8397 strncat(metrics_notification, " FALSE", 6);
8398
8399 wrqu.data.pointer = metrics_notification;
8400 wrqu.data.length = strlen(metrics_notification);
8401
8402 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8403
8404 EXIT();
8405
8406 return VOS_STATUS_SUCCESS;
8407}
8408
8409/*
8410 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8411 * 802.11r/LFR metrics reporting function to report handover initiation
8412 *
8413 */
8414VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8415 tCsrRoamInfo *pRoamInfo)
8416{
8417 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8418 union iwreq_data wrqu;
8419
8420 ENTER();
8421
8422 if (NULL == pAdapter)
8423 {
8424 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8425 return VOS_STATUS_E_FAILURE;
8426 }
8427
8428 /* create the event */
8429 memset(&wrqu, 0, sizeof(wrqu));
8430 memset(metrics_notification, 0, sizeof(metrics_notification));
8431
8432 wrqu.data.pointer = metrics_notification;
8433 wrqu.data.length = scnprintf(metrics_notification,
8434 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8435 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8436
8437 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8438
8439 EXIT();
8440
8441 return VOS_STATUS_SUCCESS;
8442}
8443#endif
8444
Jeff Johnson295189b2012-06-20 16:38:30 -07008445/*
8446 * FUNCTION: hdd_cfg80211_scan_done_callback
8447 * scanning callback function, called after finishing scan
8448 *
8449 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308450static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8452{
8453 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308454 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008456 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8457 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 struct cfg80211_scan_request *req = NULL;
8459 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308460 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308461 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008462
8463 ENTER();
8464
8465 hddLog(VOS_TRACE_LEVEL_INFO,
8466 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008467 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 __func__, halHandle, pContext, (int) scanId, (int) status);
8469
Kiet Lamac06e2c2013-10-23 16:25:07 +05308470 pScanInfo->mScanPendingCounter = 0;
8471
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308473 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 &pScanInfo->scan_req_completion_event,
8475 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308476 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308478 hddLog(VOS_TRACE_LEVEL_ERROR,
8479 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008481 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 }
8483
Yue Maef608272013-04-08 23:09:17 -07008484 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 {
8486 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008487 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 }
8489
8490 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308491 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 {
8493 hddLog(VOS_TRACE_LEVEL_INFO,
8494 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008495 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 (int) scanId);
8497 }
8498
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308499 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 pAdapter);
8501
8502 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008504
8505
8506 /* If any client wait scan result through WEXT
8507 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008508 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 {
8510 /* The other scan request waiting for current scan finish
8511 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008512 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008514 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 }
8516 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008517 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 {
8519 struct net_device *dev = pAdapter->dev;
8520 union iwreq_data wrqu;
8521 int we_event;
8522 char *msg;
8523
8524 memset(&wrqu, '\0', sizeof(wrqu));
8525 we_event = SIOCGIWSCAN;
8526 msg = NULL;
8527 wireless_send_event(dev, we_event, &wrqu, msg);
8528 }
8529 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008530 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008531
8532 /* Get the Scan Req */
8533 req = pAdapter->request;
8534
8535 if (!req)
8536 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008537 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008538 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008539 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 }
8541
8542 /*
8543 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308544 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 req->n_ssids = 0;
8546 req->n_channels = 0;
8547 req->ie = 0;
8548
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008550 /* Scan is no longer pending */
8551 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008552
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008553 /*
8554 * cfg80211_scan_done informing NL80211 about completion
8555 * of scanning
8556 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308557 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8558 {
8559 aborted = true;
8560 }
8561 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008562 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008563
Jeff Johnsone7245742012-09-05 17:12:55 -07008564allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008565 /* release the wake lock at the end of the scan*/
8566 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008567
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008568 /* Acquire wakelock to handle the case where APP's tries to suspend
8569 * immediatly after the driver gets connect request(i.e after scan)
8570 * from supplicant, this result in app's is suspending and not able
8571 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308572 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008573
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008574#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308575 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8576 {
8577 wlan_hdd_tdls_scan_done_callback(pAdapter);
8578 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008579#endif
8580
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 EXIT();
8582 return 0;
8583}
8584
8585/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308586 * FUNCTION: hdd_isConnectionInProgress
8587 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008588 *
8589 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308590v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008591{
8592 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8593 hdd_station_ctx_t *pHddStaCtx = NULL;
8594 hdd_adapter_t *pAdapter = NULL;
8595 VOS_STATUS status = 0;
8596 v_U8_t staId = 0;
8597 v_U8_t *staMac = NULL;
8598
c_hpothu9b781ba2013-12-30 20:57:45 +05308599 if (TRUE == pHddCtx->btCoexModeSet)
8600 {
8601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308602 FL("BTCoex Mode operation in progress"));
8603 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308604 }
8605
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008606 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8607
8608 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8609 {
8610 pAdapter = pAdapterNode->pAdapter;
8611
8612 if( pAdapter )
8613 {
8614 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308615 "%s: Adapter with device mode %s (%d) exists",
8616 __func__, hdd_device_modetoString(pAdapter->device_mode),
8617 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308618 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8619 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8620 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8621 (eConnectionState_Connecting ==
8622 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8623 {
8624 hddLog(VOS_TRACE_LEVEL_ERROR,
8625 "%s: %p(%d) Connection is in progress", __func__,
8626 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8627 return VOS_TRUE;
8628 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008629 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308630 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8631 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008632 {
8633 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308635 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008636 {
8637 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8638 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008639 "%s: client " MAC_ADDRESS_STR
8640 " is in the middle of WPS/EAPOL exchange.", __func__,
8641 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308642 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008643 }
8644 }
8645 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8646 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8647 {
8648 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8649 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308650 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008651 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8652 {
8653 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8654
8655 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008656 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8657 "middle of WPS/EAPOL exchange.", __func__,
8658 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308659 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008660 }
8661 }
8662 }
8663 }
8664 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8665 pAdapterNode = pNext;
8666 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308667 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308668}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008669
8670/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308671 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008672 * this scan respond to scan trigger and update cfg80211 scan database
8673 * later, scan dump command can be used to recieve scan results
8674 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308675int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008676#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8677 struct net_device *dev,
8678#endif
8679 struct cfg80211_scan_request *request)
8680{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308681 hdd_adapter_t *pAdapter = NULL;
8682 hdd_context_t *pHddCtx = NULL;
8683 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308684 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 tCsrScanRequest scanRequest;
8686 tANI_U8 *channelList = NULL, i;
8687 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308688 int status;
8689 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008691
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308692#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8693 struct net_device *dev = NULL;
8694 if (NULL == request)
8695 {
8696 hddLog(VOS_TRACE_LEVEL_ERROR,
8697 "%s: scan req param null", __func__);
8698 return -EINVAL;
8699 }
8700 dev = request->wdev->netdev;
8701#endif
8702
8703 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8704 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8705 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8706
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 ENTER();
8708
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308709
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8711 __func__, hdd_device_modetoString(pAdapter->device_mode),
8712 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308714 status = wlan_hdd_validate_context(pHddCtx);
8715
8716 if (0 != status)
8717 {
8718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8719 "%s: HDD context is not valid", __func__);
8720 return status;
8721 }
8722
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308723 if (NULL == pwextBuf)
8724 {
8725 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8726 __func__);
8727 return -EIO;
8728 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308729 cfg_param = pHddCtx->cfg_ini;
8730 pScanInfo = &pHddCtx->scan_info;
8731
Jeff Johnson295189b2012-06-20 16:38:30 -07008732#ifdef WLAN_BTAMP_FEATURE
8733 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008734 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008736 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 "%s: No scanning when AMP is on", __func__);
8738 return -EOPNOTSUPP;
8739 }
8740#endif
8741 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008742 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008744 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308745 "%s: Not scanning on device_mode = %s (%d)",
8746 __func__, hdd_device_modetoString(pAdapter->device_mode),
8747 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 return -EOPNOTSUPP;
8749 }
8750
8751 if (TRUE == pScanInfo->mScanPending)
8752 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308753 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8754 {
8755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8756 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008757 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 }
8759
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308760 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008761 //Channel and action frame is pending
8762 //Otherwise Cancel Remain On Channel and allow Scan
8763 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008764 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008765 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008767 return -EBUSY;
8768 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008769#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008770 /* if tdls disagree scan right now, return immediately.
8771 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8772 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8773 */
8774 status = wlan_hdd_tdls_scan_callback (pAdapter,
8775 wiphy,
8776#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8777 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008778#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008779 request);
8780 if(status <= 0)
8781 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308782 if(!status)
8783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8784 "scan rejected %d", __func__, status);
8785 else
8786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8787 __func__, status);
8788
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008789 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008790 }
8791#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008792
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8794 {
8795 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008796 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308798 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8800 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308801 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 "%s: MAX TM Level Scan not allowed", __func__);
8803 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308804 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 }
8806 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8807
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008808 /* Check if scan is allowed at this point of time.
8809 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308810 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008811 {
8812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8813 return -EBUSY;
8814 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8817
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308818 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8819 (int)request->n_ssids);
8820
8821 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8822 * Becasue of this, driver is assuming that this is not wildcard scan and so
8823 * is not aging out the scan results.
8824 */
8825 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308827 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308829
8830 if ((request->ssids) && (0 < request->n_ssids))
8831 {
8832 tCsrSSIDInfo *SsidInfo;
8833 int j;
8834 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8835 /* Allocate num_ssid tCsrSSIDInfo structure */
8836 SsidInfo = scanRequest.SSIDs.SSIDList =
8837 ( tCsrSSIDInfo *)vos_mem_malloc(
8838 request->n_ssids*sizeof(tCsrSSIDInfo));
8839
8840 if(NULL == scanRequest.SSIDs.SSIDList)
8841 {
8842 hddLog(VOS_TRACE_LEVEL_ERROR,
8843 "%s: memory alloc failed SSIDInfo buffer", __func__);
8844 return -ENOMEM;
8845 }
8846
8847 /* copy all the ssid's and their length */
8848 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8849 {
8850 /* get the ssid length */
8851 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8852 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8853 SsidInfo->SSID.length);
8854 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8855 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8856 j, SsidInfo->SSID.ssId);
8857 }
8858 /* set the scan type to active */
8859 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8860 }
8861 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8864 TRACE_CODE_HDD_CFG80211_SCAN,
8865 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 /* set the scan type to active */
8867 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308869 else
8870 {
8871 /*Set the scan type to default type, in this case it is ACTIVE*/
8872 scanRequest.scanType = pScanInfo->scan_mode;
8873 }
8874 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8875 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
8877 /* set BSSType to default type */
8878 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8879
8880 /*TODO: scan the requested channels only*/
8881
8882 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308883 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308885 hddLog(VOS_TRACE_LEVEL_WARN,
8886 "No of Scan Channels exceeded limit: %d", request->n_channels);
8887 request->n_channels = MAX_CHANNEL;
8888 }
8889
8890 hddLog(VOS_TRACE_LEVEL_INFO,
8891 "No of Scan Channels: %d", request->n_channels);
8892
8893
8894 if( request->n_channels )
8895 {
8896 char chList [(request->n_channels*5)+1];
8897 int len;
8898 channelList = vos_mem_malloc( request->n_channels );
8899 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308900 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308901 hddLog(VOS_TRACE_LEVEL_ERROR,
8902 "%s: memory alloc failed channelList", __func__);
8903 status = -ENOMEM;
8904 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308905 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308906
8907 for( i = 0, len = 0; i < request->n_channels ; i++ )
8908 {
8909 channelList[i] = request->channels[i]->hw_value;
8910 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8911 }
8912
Nirav Shah20ac06f2013-12-12 18:14:06 +05308913 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308914 "Channel-List: %s ", chList);
8915 }
c_hpothu53512302014-04-15 18:49:53 +05308916
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308917 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8918 scanRequest.ChannelInfo.ChannelList = channelList;
8919
8920 /* set requestType to full scan */
8921 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8922
8923 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8924 * search (Flush on both full scan and social scan but not on single
8925 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8926 */
8927
8928 /* Supplicant does single channel scan after 8-way handshake
8929 * and in that case driver shoudnt flush scan results. If
8930 * driver flushes the scan results here and unfortunately if
8931 * the AP doesnt respond to our probe req then association
8932 * fails which is not desired
8933 */
8934
8935 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8936 {
8937 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8938 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8939 pAdapter->sessionId );
8940 }
8941
8942 if( request->ie_len )
8943 {
8944 /* save this for future association (join requires this) */
8945 /*TODO: Array needs to be converted to dynamic allocation,
8946 * as multiple ie.s can be sent in cfg80211_scan_request structure
8947 * CR 597966
8948 */
8949 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8950 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8951 pScanInfo->scanAddIE.length = request->ie_len;
8952
8953 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8954 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8955 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308957 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308959 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8960 memcpy( pwextBuf->roamProfile.addIEScan,
8961 request->ie, request->ie_len);
8962 }
8963 else
8964 {
8965 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8966 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 }
8968
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308969 }
8970 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8971 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8972
8973 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8974 request->ie_len);
8975 if (pP2pIe != NULL)
8976 {
8977#ifdef WLAN_FEATURE_P2P_DEBUG
8978 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8979 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8980 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308981 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308982 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8983 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8984 "Go nego completed to Connection is started");
8985 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8986 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308987 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308988 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8989 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308991 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8992 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8993 "Disconnected state to Connection is started");
8994 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8995 "for 4way Handshake");
8996 }
8997#endif
8998
8999 /* no_cck will be set during p2p find to disable 11b rates */
9000 if(TRUE == request->no_cck)
9001 {
9002 hddLog(VOS_TRACE_LEVEL_INFO,
9003 "%s: This is a P2P Search", __func__);
9004 scanRequest.p2pSearch = 1;
9005
9006 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309007 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309008 /* set requestType to P2P Discovery */
9009 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9010 }
9011
9012 /*
9013 Skip Dfs Channel in case of P2P Search
9014 if it is set in ini file
9015 */
9016 if(cfg_param->skipDfsChnlInP2pSearch)
9017 {
9018 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309019 }
9020 else
9021 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309022 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009024
Agarwal Ashish4f616132013-12-30 23:32:50 +05309025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 }
9027 }
9028
9029 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9030
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009031 /* acquire the wakelock to avoid the apps suspend during the scan. To
9032 * address the following issues.
9033 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9034 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9035 * for long time, this result in apps running at full power for long time.
9036 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9037 * be stuck in full power because of resume BMPS
9038 */
9039 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009040
Nirav Shah20ac06f2013-12-12 18:14:06 +05309041 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9042 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309043 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9044 scanRequest.requestType, scanRequest.scanType,
9045 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309046 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9047
Jeff Johnsone7245742012-09-05 17:12:55 -07009048 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 pAdapter->sessionId, &scanRequest, &scanId,
9050 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 if (eHAL_STATUS_SUCCESS != status)
9053 {
9054 hddLog(VOS_TRACE_LEVEL_ERROR,
9055 "%s: sme_ScanRequest returned error %d", __func__, status);
9056 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009057 if(eHAL_STATUS_RESOURCES == status)
9058 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9060 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009061 status = -EBUSY;
9062 } else {
9063 status = -EIO;
9064 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009065 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009066 goto free_mem;
9067 }
9068
9069 pScanInfo->mScanPending = TRUE;
9070 pAdapter->request = request;
9071 pScanInfo->scanId = scanId;
9072
9073 complete(&pScanInfo->scan_req_completion_event);
9074
9075free_mem:
9076 if( scanRequest.SSIDs.SSIDList )
9077 {
9078 vos_mem_free(scanRequest.SSIDs.SSIDList);
9079 }
9080
9081 if( channelList )
9082 vos_mem_free( channelList );
9083
9084 EXIT();
9085
9086 return status;
9087}
9088
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309089int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9090#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9091 struct net_device *dev,
9092#endif
9093 struct cfg80211_scan_request *request)
9094{
9095 int ret;
9096
9097 vos_ssr_protect(__func__);
9098 ret = __wlan_hdd_cfg80211_scan(wiphy,
9099#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9100 dev,
9101#endif
9102 request);
9103 vos_ssr_unprotect(__func__);
9104
9105 return ret;
9106}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009107
9108void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9109{
9110 v_U8_t iniDot11Mode =
9111 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9112 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9113
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309114 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9115 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009116 switch ( iniDot11Mode )
9117 {
9118 case eHDD_DOT11_MODE_AUTO:
9119 case eHDD_DOT11_MODE_11ac:
9120 case eHDD_DOT11_MODE_11ac_ONLY:
9121#ifdef WLAN_FEATURE_11AC
9122 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9123#else
9124 hddDot11Mode = eHDD_DOT11_MODE_11n;
9125#endif
9126 break;
9127 case eHDD_DOT11_MODE_11n:
9128 case eHDD_DOT11_MODE_11n_ONLY:
9129 hddDot11Mode = eHDD_DOT11_MODE_11n;
9130 break;
9131 default:
9132 hddDot11Mode = iniDot11Mode;
9133 break;
9134 }
9135 /* This call decides required channel bonding mode */
9136 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9137 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9138 operationChannel);
9139}
9140
Jeff Johnson295189b2012-06-20 16:38:30 -07009141/*
9142 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309143 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309145int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009146 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009147{
9148 int status = 0;
9149 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009150 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 v_U32_t roamId;
9152 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 eCsrAuthType RSNAuthType;
9154
9155 ENTER();
9156
9157 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9159
9160 status = wlan_hdd_validate_context(pHddCtx);
9161 if (status)
9162 {
9163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9164 "%s: HDD context is not valid!", __func__);
9165 return status;
9166 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309167
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9169 {
9170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9171 return -EINVAL;
9172 }
9173
9174 pRoamProfile = &pWextState->roamProfile;
9175
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309176 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009178 hdd_station_ctx_t *pHddStaCtx;
9179 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009180
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309181 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9183 {
9184 /*QoS not enabled in cfg file*/
9185 pRoamProfile->uapsd_mask = 0;
9186 }
9187 else
9188 {
9189 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309190 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009191 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9192 }
9193
9194 pRoamProfile->SSIDs.numOfSSIDs = 1;
9195 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9196 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309197 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9199 ssid, ssid_len);
9200
9201 if (bssid)
9202 {
9203 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9204 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9205 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309206 /* Save BSSID in seperate variable as well, as RoamProfile
9207 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 case of join failure we should send valid BSSID to supplicant
9209 */
9210 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9211 WNI_CFG_BSSID_LEN);
9212 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009213 else
9214 {
9215 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9216 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009217
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309218 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9219 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9221 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 /*set gen ie*/
9224 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9225 /*set auth*/
9226 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9227 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009228#ifdef FEATURE_WLAN_WAPI
9229 if (pAdapter->wapi_info.nWapiMode)
9230 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009231 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 switch (pAdapter->wapi_info.wapiAuthMode)
9233 {
9234 case WAPI_AUTH_MODE_PSK:
9235 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009236 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 pAdapter->wapi_info.wapiAuthMode);
9238 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9239 break;
9240 }
9241 case WAPI_AUTH_MODE_CERT:
9242 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009243 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 pAdapter->wapi_info.wapiAuthMode);
9245 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9246 break;
9247 }
9248 } // End of switch
9249 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9250 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9251 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009252 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 pRoamProfile->AuthType.numEntries = 1;
9254 pRoamProfile->EncryptionType.numEntries = 1;
9255 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9256 pRoamProfile->mcEncryptionType.numEntries = 1;
9257 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9258 }
9259 }
9260#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309261#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309262 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309263 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9264 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9265 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309266 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9267 sizeof (tSirGtkOffloadParams));
9268 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309269 }
9270#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 pRoamProfile->csrPersona = pAdapter->device_mode;
9272
Jeff Johnson32d95a32012-09-10 13:15:23 -07009273 if( operatingChannel )
9274 {
9275 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9276 pRoamProfile->ChannelInfo.numOfChannels = 1;
9277 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009278 else
9279 {
9280 pRoamProfile->ChannelInfo.ChannelList = NULL;
9281 pRoamProfile->ChannelInfo.numOfChannels = 0;
9282 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009283 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9284 {
9285 hdd_select_cbmode(pAdapter,operatingChannel);
9286 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309287
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009288 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9289 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309290 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009291 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009292 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9293 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309294 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9295 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309296 {
9297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9298 "%s: Set HDD connState to eConnectionState_Connecting",
9299 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009300 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9301 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 pAdapter->sessionId, pRoamProfile, &roamId);
9305
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309306 if ((eHAL_STATUS_SUCCESS != status) &&
9307 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9308 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309309
9310 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9312 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9313 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309314 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009315 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309316 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009317
9318 pRoamProfile->ChannelInfo.ChannelList = NULL;
9319 pRoamProfile->ChannelInfo.numOfChannels = 0;
9320
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 }
9322 else
9323 {
9324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9325 return -EINVAL;
9326 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009327 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 return status;
9329}
9330
9331/*
9332 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9333 * This function is used to set the authentication type (OPEN/SHARED).
9334 *
9335 */
9336static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9337 enum nl80211_auth_type auth_type)
9338{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309339 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9341
9342 ENTER();
9343
9344 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309345 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309348 hddLog(VOS_TRACE_LEVEL_INFO,
9349 "%s: set authentication type to AUTOSWITCH", __func__);
9350 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9351 break;
9352
9353 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009354#ifdef WLAN_FEATURE_VOWIFI_11R
9355 case NL80211_AUTHTYPE_FT:
9356#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309357 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 "%s: set authentication type to OPEN", __func__);
9359 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9360 break;
9361
9362 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 "%s: set authentication type to SHARED", __func__);
9365 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9366 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009367#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 "%s: set authentication type to CCKM WPA", __func__);
9371 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9372 break;
9373#endif
9374
9375
9376 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309377 hddLog(VOS_TRACE_LEVEL_ERROR,
9378 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 auth_type);
9380 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9381 return -EINVAL;
9382 }
9383
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 pHddStaCtx->conn_info.authType;
9386 return 0;
9387}
9388
9389/*
9390 * FUNCTION: wlan_hdd_set_akm_suite
9391 * This function is used to set the key mgmt type(PSK/8021x).
9392 *
9393 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309394static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 u32 key_mgmt
9396 )
9397{
9398 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9399 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309400
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 /*set key mgmt type*/
9402 switch(key_mgmt)
9403 {
9404 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309405#ifdef WLAN_FEATURE_VOWIFI_11R
9406 case WLAN_AKM_SUITE_FT_PSK:
9407#endif
9408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 __func__);
9410 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9411 break;
9412
9413 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309414#ifdef WLAN_FEATURE_VOWIFI_11R
9415 case WLAN_AKM_SUITE_FT_8021X:
9416#endif
9417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 __func__);
9419 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9420 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009421#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009422#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9423#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9424 case WLAN_AKM_SUITE_CCKM:
9425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9426 __func__);
9427 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9428 break;
9429#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009430#ifndef WLAN_AKM_SUITE_OSEN
9431#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9432 case WLAN_AKM_SUITE_OSEN:
9433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9434 __func__);
9435 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9436 break;
9437#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
9439 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 __func__, key_mgmt);
9442 return -EINVAL;
9443
9444 }
9445 return 0;
9446}
9447
9448/*
9449 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 * (NONE/WEP40/WEP104/TKIP/CCMP).
9452 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9454 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 bool ucast
9456 )
9457{
9458 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309459 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9461
9462 ENTER();
9463
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 __func__, cipher);
9468 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9469 }
9470 else
9471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309472
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309474 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 {
9476 case IW_AUTH_CIPHER_NONE:
9477 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9478 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309481 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309485 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309487
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 case WLAN_CIPHER_SUITE_TKIP:
9489 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9490 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309491
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 case WLAN_CIPHER_SUITE_CCMP:
9493 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9494 break;
9495#ifdef FEATURE_WLAN_WAPI
9496 case WLAN_CIPHER_SUITE_SMS4:
9497 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9498 break;
9499#endif
9500
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009501#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 case WLAN_CIPHER_SUITE_KRK:
9503 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9504 break;
9505#endif
9506 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 __func__, cipher);
9509 return -EOPNOTSUPP;
9510 }
9511 }
9512
9513 if (ucast)
9514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 __func__, encryptionType);
9517 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9518 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309519 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 encryptionType;
9521 }
9522 else
9523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309524 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 __func__, encryptionType);
9526 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9527 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9528 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9529 }
9530
9531 return 0;
9532}
9533
9534
9535/*
9536 * FUNCTION: wlan_hdd_cfg80211_set_ie
9537 * This function is used to parse WPA/RSN IE's.
9538 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309539int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9540 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 size_t ie_len
9542 )
9543{
9544 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9545 u8 *genie = ie;
9546 v_U16_t remLen = ie_len;
9547#ifdef FEATURE_WLAN_WAPI
9548 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9549 u16 *tmp;
9550 v_U16_t akmsuiteCount;
9551 int *akmlist;
9552#endif
9553 ENTER();
9554
9555 /* clear previous assocAddIE */
9556 pWextState->assocAddIE.length = 0;
9557 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009558 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
9560 while (remLen >= 2)
9561 {
9562 v_U16_t eLen = 0;
9563 v_U8_t elementId;
9564 elementId = *genie++;
9565 eLen = *genie++;
9566 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309567
Arif Hussain6d2a3322013-11-17 19:50:10 -08009568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309570
9571 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309573 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009574 if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309576 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 "%s: Invalid WPA IE", __func__);
9578 return -EINVAL;
9579 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 {
9582 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309585
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9587 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009588 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9589 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 VOS_ASSERT(0);
9591 return -ENOMEM;
9592 }
9593 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9594 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9595 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9598 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9599 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9600 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9602 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9604 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9605 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9606 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9607 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9608 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309609 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309610 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 {
9612 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309613 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309615
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9617 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009618 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9619 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009620 VOS_ASSERT(0);
9621 return -ENOMEM;
9622 }
9623 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9624 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9625 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9628 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009630#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9632 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 /*Consider WFD IE, only for P2P Client */
9634 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9635 {
9636 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309637 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309639
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9641 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009642 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9643 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 VOS_ASSERT(0);
9645 return -ENOMEM;
9646 }
9647 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9648 // WPS IE + P2P IE + WFD IE
9649 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9650 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9653 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9654 }
9655#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009656 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309657 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009658 HS20_OUI_TYPE_SIZE)) )
9659 {
9660 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309661 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009662 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009663
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009664 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9665 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009666 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9667 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009668 VOS_ASSERT(0);
9669 return -ENOMEM;
9670 }
9671 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9672 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009673
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009674 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9675 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9676 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009677 /* Appending OSEN Information Element in Assiciation Request */
9678 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9679 OSEN_OUI_TYPE_SIZE)) )
9680 {
9681 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9682 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9683 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009684
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009685 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9686 {
9687 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9688 "Need bigger buffer space");
9689 VOS_ASSERT(0);
9690 return -ENOMEM;
9691 }
9692 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9693 pWextState->assocAddIE.length += eLen + 2;
9694
9695 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9696 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9697 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9698 }
9699
9700 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009701 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9702
9703 /* populating as ADDIE in beacon frames */
9704 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9705 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9706 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9707 {
9708 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9709 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9710 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9711 {
9712 hddLog(LOGE,
9713 "Coldn't pass "
9714 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9715 }
9716 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9717 else
9718 hddLog(LOGE,
9719 "Could not pass on "
9720 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9721
9722 /* IBSS mode doesn't contain params->proberesp_ies still
9723 beaconIE's need to be populated in probe response frames */
9724 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9725 {
9726 u16 rem_probe_resp_ie_len = eLen + 2;
9727 u8 probe_rsp_ie_len[3] = {0};
9728 u8 counter = 0;
9729
9730 /* Check Probe Resp Length if it is greater then 255 then
9731 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9732 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9733 not able Store More then 255 bytes into One Variable */
9734
9735 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9736 {
9737 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9738 {
9739 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9740 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9741 }
9742 else
9743 {
9744 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9745 rem_probe_resp_ie_len = 0;
9746 }
9747 }
9748
9749 rem_probe_resp_ie_len = 0;
9750
9751 if (probe_rsp_ie_len[0] > 0)
9752 {
9753 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9754 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9755 (tANI_U8*)(genie - 2),
9756 probe_rsp_ie_len[0], NULL,
9757 eANI_BOOLEAN_FALSE)
9758 == eHAL_STATUS_FAILURE)
9759 {
9760 hddLog(LOGE,
9761 "Could not pass"
9762 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9763 }
9764 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9765 }
9766
9767 if (probe_rsp_ie_len[1] > 0)
9768 {
9769 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9770 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9771 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9772 probe_rsp_ie_len[1], NULL,
9773 eANI_BOOLEAN_FALSE)
9774 == eHAL_STATUS_FAILURE)
9775 {
9776 hddLog(LOGE,
9777 "Could not pass"
9778 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9779 }
9780 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9781 }
9782
9783 if (probe_rsp_ie_len[2] > 0)
9784 {
9785 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9786 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9787 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9788 probe_rsp_ie_len[2], NULL,
9789 eANI_BOOLEAN_FALSE)
9790 == eHAL_STATUS_FAILURE)
9791 {
9792 hddLog(LOGE,
9793 "Could not pass"
9794 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9795 }
9796 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9797 }
9798
9799 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9800 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9801 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9802 {
9803 hddLog(LOGE,
9804 "Could not pass"
9805 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9806 }
9807 }
9808 else
9809 {
9810 // Reset WNI_CFG_PROBE_RSP Flags
9811 wlan_hdd_reset_prob_rspies(pAdapter);
9812
9813 hddLog(VOS_TRACE_LEVEL_INFO,
9814 "%s: No Probe Response IE received in set beacon",
9815 __func__);
9816 }
9817 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 break;
9819 case DOT11F_EID_RSN:
9820 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9821 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9822 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9823 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9824 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9825 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009826 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9827 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309828 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009829 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309830 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009831 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309832
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009833 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9834 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009835 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9836 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009837 VOS_ASSERT(0);
9838 return -ENOMEM;
9839 }
9840 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9841 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309842
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009843 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9844 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9845 break;
9846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009847#ifdef FEATURE_WLAN_WAPI
9848 case WLAN_EID_WAPI:
9849 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009850 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 pAdapter->wapi_info.nWapiMode);
9852 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309853 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 akmsuiteCount = WPA_GET_LE16(tmp);
9855 tmp = tmp + 1;
9856 akmlist = (int *)(tmp);
9857 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9858 {
9859 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9860 }
9861 else
9862 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009863 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 VOS_ASSERT(0);
9865 return -EINVAL;
9866 }
9867
9868 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9869 {
9870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009871 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309875 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009877 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9879 }
9880 break;
9881#endif
9882 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009885 /* when Unknown IE is received we should break and continue
9886 * to the next IE in the buffer instead we were returning
9887 * so changing this to break */
9888 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 }
9890 genie += eLen;
9891 remLen -= eLen;
9892 }
9893 EXIT();
9894 return 0;
9895}
9896
9897/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309898 * FUNCTION: hdd_isWPAIEPresent
9899 * Parse the received IE to find the WPA IE
9900 *
9901 */
9902static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9903{
9904 v_U8_t eLen = 0;
9905 v_U16_t remLen = ie_len;
9906 v_U8_t elementId = 0;
9907
9908 while (remLen >= 2)
9909 {
9910 elementId = *ie++;
9911 eLen = *ie++;
9912 remLen -= 2;
9913 if (eLen > remLen)
9914 {
9915 hddLog(VOS_TRACE_LEVEL_ERROR,
9916 "%s: IE length is wrong %d", __func__, eLen);
9917 return FALSE;
9918 }
9919 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9920 {
9921 /* OUI - 0x00 0X50 0XF2
9922 WPA Information Element - 0x01
9923 WPA version - 0x01*/
9924 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9925 return TRUE;
9926 }
9927 ie += eLen;
9928 remLen -= eLen;
9929 }
9930 return FALSE;
9931}
9932
9933/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309935 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 * parameters during connect operation.
9937 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 struct cfg80211_connect_params *req
9940 )
9941{
9942 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309943 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 ENTER();
9945
9946 /*set wpa version*/
9947 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9948
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309949 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009950 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309951 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 {
9953 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9954 }
9955 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9956 {
9957 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9958 }
9959 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309960
9961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 pWextState->wpaVersion);
9963
9964 /*set authentication type*/
9965 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9966
9967 if (0 > status)
9968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 "%s: failed to set authentication type ", __func__);
9971 return status;
9972 }
9973
9974 /*set key mgmt type*/
9975 if (req->crypto.n_akm_suites)
9976 {
9977 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9978 if (0 > status)
9979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 __func__);
9982 return status;
9983 }
9984 }
9985
9986 /*set pairwise cipher type*/
9987 if (req->crypto.n_ciphers_pairwise)
9988 {
9989 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9990 req->crypto.ciphers_pairwise[0], true);
9991 if (0 > status)
9992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 "%s: failed to set unicast cipher type", __func__);
9995 return status;
9996 }
9997 }
9998 else
9999 {
10000 /*Reset previous cipher suite to none*/
10001 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10002 if (0 > status)
10003 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010004 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 "%s: failed to set unicast cipher type", __func__);
10006 return status;
10007 }
10008 }
10009
10010 /*set group cipher type*/
10011 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10012 false);
10013
10014 if (0 > status)
10015 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 __func__);
10018 return status;
10019 }
10020
Chet Lanctot186b5732013-03-18 10:26:30 -070010021#ifdef WLAN_FEATURE_11W
10022 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10023#endif
10024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10026 if (req->ie_len)
10027 {
10028 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10029 if ( 0 > status)
10030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 __func__);
10033 return status;
10034 }
10035 }
10036
10037 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010038 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 {
10040 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10041 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10042 )
10043 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010044 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 __func__);
10049 return -EOPNOTSUPP;
10050 }
10051 else
10052 {
10053 u8 key_len = req->key_len;
10054 u8 key_idx = req->key_idx;
10055
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010056 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 && (CSR_MAX_NUM_KEY > key_idx)
10058 )
10059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 hddLog(VOS_TRACE_LEVEL_INFO,
10061 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 __func__, key_idx, key_len);
10063 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010064 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010066 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 (u8)key_len;
10068 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10069 }
10070 }
10071 }
10072 }
10073
10074 return status;
10075}
10076
10077/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010078 * FUNCTION: wlan_hdd_try_disconnect
10079 * This function is used to disconnect from previous
10080 * connection
10081 */
10082static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10083{
10084 long ret = 0;
10085 hdd_station_ctx_t *pHddStaCtx;
10086 eMib_dot11DesiredBssType connectedBssType;
10087
10088 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10089
10090 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10091
10092 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10093 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10094 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10095 {
10096 /* Issue disconnect to CSR */
10097 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10098 if( eHAL_STATUS_SUCCESS ==
10099 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10100 pAdapter->sessionId,
10101 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10102 {
10103 ret = wait_for_completion_interruptible_timeout(
10104 &pAdapter->disconnect_comp_var,
10105 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10106 if (0 >= ret)
10107 {
10108 hddLog(LOGE, FL("Failed to receive disconnect event"));
10109 return -EALREADY;
10110 }
10111 }
10112 }
10113 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10114 {
10115 ret = wait_for_completion_interruptible_timeout(
10116 &pAdapter->disconnect_comp_var,
10117 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10118 if (0 >= ret)
10119 {
10120 hddLog(LOGE, FL("Failed to receive disconnect event"));
10121 return -EALREADY;
10122 }
10123 }
10124
10125 return 0;
10126}
10127
10128/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010129 * FUNCTION: __wlan_hdd_cfg80211_connect
10130 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010132static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 struct net_device *ndev,
10134 struct cfg80211_connect_params *req
10135 )
10136{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010137 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010140 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010141
10142 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010143
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10145 TRACE_CODE_HDD_CFG80211_CONNECT,
10146 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010147 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010148 "%s: device_mode = %s (%d)", __func__,
10149 hdd_device_modetoString(pAdapter->device_mode),
10150 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010151
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010153 if (!pHddCtx)
10154 {
10155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10156 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010157 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010158 }
10159
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010160 status = wlan_hdd_validate_context(pHddCtx);
10161
10162 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10165 "%s: HDD context is not valid", __func__);
10166 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 }
10168
Agarwal Ashish51325b52014-06-16 16:50:49 +053010169 if (vos_max_concurrent_connections_reached()) {
10170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10171 return -ECONNREFUSED;
10172 }
10173
Jeff Johnson295189b2012-06-20 16:38:30 -070010174#ifdef WLAN_BTAMP_FEATURE
10175 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010176 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010178 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010180 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 }
10182#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010183
10184 //If Device Mode is Station Concurrent Sessions Exit BMps
10185 //P2P Mode will be taken care in Open/close adapter
10186 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010187 (vos_concurrent_open_sessions_running())) {
10188 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10189 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010190 }
10191
10192 /*Try disconnecting if already in connected state*/
10193 status = wlan_hdd_try_disconnect(pAdapter);
10194 if ( 0 > status)
10195 {
10196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10197 " connection"));
10198 return -EALREADY;
10199 }
10200
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010202 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010203
10204 if ( 0 > status)
10205 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 __func__);
10208 return status;
10209 }
10210
Mohit Khanna765234a2012-09-11 15:08:35 -070010211 if ( req->channel )
10212 {
10213 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10214 req->ssid_len, req->bssid,
10215 req->channel->hw_value);
10216 }
10217 else
10218 {
10219 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010220 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010222
10223 if (0 > status)
10224 {
10225 //ReEnable BMPS if disabled
10226 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10227 (NULL != pHddCtx))
10228 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010229 if (pHddCtx->hdd_wlan_suspended)
10230 {
10231 hdd_set_pwrparams(pHddCtx);
10232 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 //ReEnable Bmps and Imps back
10234 hdd_enable_bmps_imps(pHddCtx);
10235 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 return status;
10238 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010240 EXIT();
10241 return status;
10242}
10243
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010244static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10245 struct net_device *ndev,
10246 struct cfg80211_connect_params *req)
10247{
10248 int ret;
10249 vos_ssr_protect(__func__);
10250 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10251 vos_ssr_unprotect(__func__);
10252
10253 return ret;
10254}
Jeff Johnson295189b2012-06-20 16:38:30 -070010255
10256/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010257 * FUNCTION: wlan_hdd_disconnect
10258 * This function is used to issue a disconnect request to SME
10259 */
10260int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10261{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010262 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010263 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010264 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010265 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010266
10267 status = wlan_hdd_validate_context(pHddCtx);
10268
10269 if (0 != status)
10270 {
10271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10272 "%s: HDD context is not valid", __func__);
10273 return status;
10274 }
10275
10276 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10278 "%s: Set HDD connState to eConnectionState_Disconnecting",
10279 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010280 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010281 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010282
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010283 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010284
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010285 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10286 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010287 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10288 {
10289 hddLog(VOS_TRACE_LEVEL_INFO,
10290 FL("status = %d, already disconnected"),
10291 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010292
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010293 }
10294 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010295 {
10296 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010297 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010298 __func__, (int)status );
10299 return -EINVAL;
10300 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010301 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010302 &pAdapter->disconnect_comp_var,
10303 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010304 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010305 {
10306 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010307 "%s: Failed to disconnect, timed out", __func__);
10308 return -ETIMEDOUT;
10309 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010310 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010311 {
10312 hddLog(VOS_TRACE_LEVEL_ERROR,
10313 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010314 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010315 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10317 FL("Set HDD connState to eConnectionState_NotConnected"));
10318 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10319
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010320 /*stop tx queues*/
10321 netif_tx_disable(pAdapter->dev);
10322 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010323 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010324}
10325
10326
10327/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010328 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 * This function is used to issue a disconnect request to SME
10330 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010331static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 struct net_device *dev,
10333 u16 reason
10334 )
10335{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010336 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010337 tCsrRoamProfile *pRoamProfile =
10338 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010339 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010340 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10341 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010342#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010343 tANI_U8 staIdx;
10344#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010347
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010348 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10349 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10350 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010351 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10352 __func__, hdd_device_modetoString(pAdapter->device_mode),
10353 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010355 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10356 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010357
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010358 status = wlan_hdd_validate_context(pHddCtx);
10359
10360 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10363 "%s: HDD context is not valid", __func__);
10364 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 if (NULL != pRoamProfile)
10368 {
10369 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010370 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10371 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010373 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010375 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 switch(reason)
10377 {
10378 case WLAN_REASON_MIC_FAILURE:
10379 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10380 break;
10381
10382 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10383 case WLAN_REASON_DISASSOC_AP_BUSY:
10384 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10385 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10386 break;
10387
10388 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10389 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010390 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10392 break;
10393
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 default:
10395 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10396 break;
10397 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010398 pScanInfo = &pHddCtx->scan_info;
10399 if (pScanInfo->mScanPending)
10400 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010401 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010402 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010403 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10404 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010405 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010406
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010407#ifdef FEATURE_WLAN_TDLS
10408 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010409 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010410 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010411 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10412 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010413 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010414 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010415 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010416 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010417 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010418 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010419 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010420 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010421 pAdapter->sessionId,
10422 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010423 }
10424 }
10425#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010426 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010427 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10428 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 {
10430 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010431 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 __func__, (int)status );
10433 return -EINVAL;
10434 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010436 else
10437 {
10438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10439 "called while in %d state", __func__,
10440 pHddStaCtx->conn_info.connState);
10441 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 }
10443 else
10444 {
10445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10446 }
10447
10448 return status;
10449}
10450
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010451static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10452 struct net_device *dev,
10453 u16 reason
10454 )
10455{
10456 int ret;
10457 vos_ssr_protect(__func__);
10458 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10459 vos_ssr_unprotect(__func__);
10460
10461 return ret;
10462}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010463
Jeff Johnson295189b2012-06-20 16:38:30 -070010464/*
10465 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010466 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 * settings in IBSS mode.
10468 */
10469static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010470 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 struct cfg80211_ibss_params *params
10472 )
10473{
10474 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010475 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10477 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 ENTER();
10480
10481 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010482 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010483
10484 if (params->ie_len && ( NULL != params->ie) )
10485 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010486 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10487 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 {
10489 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10490 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10491 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010492 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010494 tDot11fIEWPA dot11WPAIE;
10495 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010496 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010497
Wilson Yang00256342013-10-10 23:13:38 -070010498 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010499 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10500 params->ie_len, DOT11F_EID_WPA);
10501 if ( NULL != ie )
10502 {
10503 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10504 // Unpack the WPA IE
10505 //Skip past the EID byte and length byte - and four byte WiFi OUI
10506 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10507 &ie[2+4],
10508 ie[1] - 4,
10509 &dot11WPAIE);
10510 /*Extract the multicast cipher, the encType for unicast
10511 cipher for wpa-none is none*/
10512 encryptionType =
10513 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010516
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10518
10519 if (0 > status)
10520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010521 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 __func__);
10523 return status;
10524 }
10525 }
10526
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 pWextState->roamProfile.AuthType.authType[0] =
10528 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10530
10531 if (params->privacy)
10532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 /* Security enabled IBSS, At this time there is no information available
10534 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010536 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 *enable privacy bit in beacons */
10540
10541 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10542 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010543 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10544 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10546 pWextState->roamProfile.EncryptionType.numEntries = 1;
10547 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 return status;
10549}
10550
10551/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010552 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010553 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010555static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 struct net_device *dev,
10557 struct cfg80211_ibss_params *params
10558 )
10559{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10562 tCsrRoamProfile *pRoamProfile;
10563 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010564 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10566 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010567
10568 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010569
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010570 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10571 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10572 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010573 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010574 "%s: device_mode = %s (%d)", __func__,
10575 hdd_device_modetoString(pAdapter->device_mode),
10576 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010577
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010578 status = wlan_hdd_validate_context(pHddCtx);
10579
10580 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10583 "%s: HDD context is not valid", __func__);
10584 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 }
10586
10587 if (NULL == pWextState)
10588 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010589 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 __func__);
10591 return -EIO;
10592 }
10593
Agarwal Ashish51325b52014-06-16 16:50:49 +053010594 if (vos_max_concurrent_connections_reached()) {
10595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10596 return -ECONNREFUSED;
10597 }
10598
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010599 /*Try disconnecting if already in connected state*/
10600 status = wlan_hdd_try_disconnect(pAdapter);
10601 if ( 0 > status)
10602 {
10603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10604 " IBSS connection"));
10605 return -EALREADY;
10606 }
10607
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 pRoamProfile = &pWextState->roamProfile;
10609
10610 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10611 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010612 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010613 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010614 return -EINVAL;
10615 }
10616
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010617 /* BSSID is provided by upper layers hence no need to AUTO generate */
10618 if (NULL != params->bssid) {
10619 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10620 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10621 hddLog (VOS_TRACE_LEVEL_ERROR,
10622 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10623 return -EIO;
10624 }
10625 }
krunal sonie9002db2013-11-25 14:24:17 -080010626 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10627 {
10628 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10629 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10630 {
10631 hddLog (VOS_TRACE_LEVEL_ERROR,
10632 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10633 return -EIO;
10634 }
10635 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10636 if (!params->bssid)
10637 {
10638 hddLog (VOS_TRACE_LEVEL_ERROR,
10639 "%s:Failed memory allocation", __func__);
10640 return -EIO;
10641 }
10642 vos_mem_copy((v_U8_t *)params->bssid,
10643 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10644 VOS_MAC_ADDR_SIZE);
10645 alloc_bssid = VOS_TRUE;
10646 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010647
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010649 if (NULL !=
10650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10651 params->chandef.chan)
10652#else
10653 params->channel)
10654#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 {
10656 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010657 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10658 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10660 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010661
10662 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010663 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010664 ieee80211_frequency_to_channel(
10665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10666 params->chandef.chan->center_freq);
10667#else
10668 params->channel->center_freq);
10669#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010670
10671 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10672 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10675 __func__);
10676 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010677 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010678
10679 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010681 if (channelNum == validChan[indx])
10682 {
10683 break;
10684 }
10685 }
10686 if (indx >= numChans)
10687 {
10688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 __func__, channelNum);
10690 return -EINVAL;
10691 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010692 /* Set the Operational Channel */
10693 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10694 channelNum);
10695 pRoamProfile->ChannelInfo.numOfChannels = 1;
10696 pHddStaCtx->conn_info.operationChannel = channelNum;
10697 pRoamProfile->ChannelInfo.ChannelList =
10698 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010699 }
10700
10701 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 if (status < 0)
10704 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 __func__);
10707 return status;
10708 }
10709
10710 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010711 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010712 params->ssid_len, params->bssid,
10713 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010714
10715 if (0 > status)
10716 {
10717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10718 return status;
10719 }
10720
krunal sonie9002db2013-11-25 14:24:17 -080010721 if (NULL != params->bssid &&
10722 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10723 alloc_bssid == VOS_TRUE)
10724 {
10725 vos_mem_free(params->bssid);
10726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 return 0;
10728}
10729
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010730static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10731 struct net_device *dev,
10732 struct cfg80211_ibss_params *params
10733 )
10734{
10735 int ret = 0;
10736
10737 vos_ssr_protect(__func__);
10738 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10739 vos_ssr_unprotect(__func__);
10740
10741 return ret;
10742}
10743
Jeff Johnson295189b2012-06-20 16:38:30 -070010744/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010745 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010746 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010747 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010748static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 struct net_device *dev
10750 )
10751{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010753 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10754 tCsrRoamProfile *pRoamProfile;
10755 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010756 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010757
10758 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10761 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10762 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010763 status = wlan_hdd_validate_context(pHddCtx);
10764
10765 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010766 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10768 "%s: HDD context is not valid", __func__);
10769 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010770 }
10771
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10773 hdd_device_modetoString(pAdapter->device_mode),
10774 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 if (NULL == pWextState)
10776 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010777 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 __func__);
10779 return -EIO;
10780 }
10781
10782 pRoamProfile = &pWextState->roamProfile;
10783
10784 /* Issue disconnect only if interface type is set to IBSS */
10785 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010787 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 __func__);
10789 return -EINVAL;
10790 }
10791
10792 /* Issue Disconnect request */
10793 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10794 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10795 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10796
10797 return 0;
10798}
10799
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010800static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10801 struct net_device *dev
10802 )
10803{
10804 int ret = 0;
10805
10806 vos_ssr_protect(__func__);
10807 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10808 vos_ssr_unprotect(__func__);
10809
10810 return ret;
10811}
10812
Jeff Johnson295189b2012-06-20 16:38:30 -070010813/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010814 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 * This function is used to set the phy parameters
10816 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10817 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010818static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 u32 changed)
10820{
10821 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10822 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010823 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010824
10825 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10827 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10828 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010829 status = wlan_hdd_validate_context(pHddCtx);
10830
10831 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10834 "%s: HDD context is not valid", __func__);
10835 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010836 }
10837
Jeff Johnson295189b2012-06-20 16:38:30 -070010838 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10839 {
10840 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10841 WNI_CFG_RTS_THRESHOLD_STAMAX :
10842 wiphy->rts_threshold;
10843
10844 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010845 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010847 hddLog(VOS_TRACE_LEVEL_ERROR,
10848 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 __func__, rts_threshold);
10850 return -EINVAL;
10851 }
10852
10853 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10854 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010857 hddLog(VOS_TRACE_LEVEL_ERROR,
10858 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 __func__, rts_threshold);
10860 return -EIO;
10861 }
10862
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 rts_threshold);
10865 }
10866
10867 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10868 {
10869 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10870 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10871 wiphy->frag_threshold;
10872
10873 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010874 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010876 hddLog(VOS_TRACE_LEVEL_ERROR,
10877 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 frag_threshold);
10879 return -EINVAL;
10880 }
10881
10882 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10883 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 hddLog(VOS_TRACE_LEVEL_ERROR,
10887 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 __func__, frag_threshold);
10889 return -EIO;
10890 }
10891
10892 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10893 frag_threshold);
10894 }
10895
10896 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10897 || (changed & WIPHY_PARAM_RETRY_LONG))
10898 {
10899 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10900 wiphy->retry_short :
10901 wiphy->retry_long;
10902
10903 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10904 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010907 __func__, retry_value);
10908 return -EINVAL;
10909 }
10910
10911 if (changed & WIPHY_PARAM_RETRY_SHORT)
10912 {
10913 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10914 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010915 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010917 hddLog(VOS_TRACE_LEVEL_ERROR,
10918 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 __func__, retry_value);
10920 return -EIO;
10921 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 __func__, retry_value);
10924 }
10925 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10926 {
10927 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10928 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010929 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010931 hddLog(VOS_TRACE_LEVEL_ERROR,
10932 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 __func__, retry_value);
10934 return -EIO;
10935 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010936 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 __func__, retry_value);
10938 }
10939 }
10940
10941 return 0;
10942}
10943
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010944static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10945 u32 changed)
10946{
10947 int ret;
10948
10949 vos_ssr_protect(__func__);
10950 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10951 vos_ssr_unprotect(__func__);
10952
10953 return ret;
10954}
10955
Jeff Johnson295189b2012-06-20 16:38:30 -070010956/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010957 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 * This function is used to set the txpower
10959 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010960static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010961#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10962 struct wireless_dev *wdev,
10963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010964#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010965 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010966#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010967 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010968#endif
10969 int dbm)
10970{
10971 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010972 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10974 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010975 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010976
10977 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010978 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10979 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10980 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010981 status = wlan_hdd_validate_context(pHddCtx);
10982
10983 if (0 != status)
10984 {
10985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10986 "%s: HDD context is not valid", __func__);
10987 return status;
10988 }
10989
10990 hHal = pHddCtx->hHal;
10991
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010992 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10993 dbm, ccmCfgSetCallback,
10994 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10998 return -EIO;
10999 }
11000
11001 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11002 dbm);
11003
11004 switch(type)
11005 {
11006 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11007 /* Fall through */
11008 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11009 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11012 __func__);
11013 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011014 }
11015 break;
11016 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 __func__);
11019 return -EOPNOTSUPP;
11020 break;
11021 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11023 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 return -EIO;
11025 }
11026
11027 return 0;
11028}
11029
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011030static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11031#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11032 struct wireless_dev *wdev,
11033#endif
11034#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11035 enum tx_power_setting type,
11036#else
11037 enum nl80211_tx_power_setting type,
11038#endif
11039 int dbm)
11040{
11041 int ret;
11042 vos_ssr_protect(__func__);
11043 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11044#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11045 wdev,
11046#endif
11047#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11048 type,
11049#else
11050 type,
11051#endif
11052 dbm);
11053 vos_ssr_unprotect(__func__);
11054
11055 return ret;
11056}
11057
Jeff Johnson295189b2012-06-20 16:38:30 -070011058/*
11059 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11060 * This function is used to read the txpower
11061 */
Yue Maf49ba872013-08-19 12:04:25 -070011062static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11063#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11064 struct wireless_dev *wdev,
11065#endif
11066 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011067{
11068
11069 hdd_adapter_t *pAdapter;
11070 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011071 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011072
Jeff Johnsone7245742012-09-05 17:12:55 -070011073 ENTER();
11074
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011075 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011076
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011077 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011078 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11080 "%s: HDD context is not valid", __func__);
11081 *dbm = 0;
11082 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011083 }
11084
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11086 if (NULL == pAdapter)
11087 {
11088 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11089 return -ENOENT;
11090 }
11091
11092 wlan_hdd_get_classAstats(pAdapter);
11093 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11094
Jeff Johnsone7245742012-09-05 17:12:55 -070011095 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 return 0;
11097}
11098
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011099static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 u8* mac, struct station_info *sinfo)
11101{
11102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11103 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11104 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011105 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011106
11107 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11108 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011109
11110 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11111 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11112 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11113 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11114 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11115 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11116 tANI_U16 maxRate = 0;
11117 tANI_U16 myRate;
11118 tANI_U16 currentRate = 0;
11119 tANI_U8 maxSpeedMCS = 0;
11120 tANI_U8 maxMCSIdx = 0;
11121 tANI_U8 rateFlag = 1;
11122 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011123 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011124 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125
Leo Chang6f8870f2013-03-26 18:11:36 -070011126#ifdef WLAN_FEATURE_11AC
11127 tANI_U32 vht_mcs_map;
11128 eDataRate11ACMaxMcs vhtMaxMcs;
11129#endif /* WLAN_FEATURE_11AC */
11130
Jeff Johnsone7245742012-09-05 17:12:55 -070011131 ENTER();
11132
Jeff Johnson295189b2012-06-20 16:38:30 -070011133 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11134 (0 == ssidlen))
11135 {
11136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11137 " Invalid ssidlen, %d", __func__, ssidlen);
11138 /*To keep GUI happy*/
11139 return 0;
11140 }
11141
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011142 status = wlan_hdd_validate_context(pHddCtx);
11143
11144 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011145 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11147 "%s: HDD context is not valid", __func__);
11148 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011149 }
11150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151
Kiet Lam3b17fc82013-09-27 05:24:08 +053011152 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11153 sinfo->filled |= STATION_INFO_SIGNAL;
11154
c_hpothu09f19542014-05-30 21:53:31 +053011155 wlan_hdd_get_station_stats(pAdapter);
11156 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11157
11158 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011159 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11160 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11161 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11162 {
11163 rate_flags = pAdapter->maxRateFlags;
11164 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011165
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 //convert to the UI units of 100kbps
11167 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11168
11169#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011170 pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 sinfo->signal,
11172 pCfg->reportMaxLinkSpeed,
11173 myRate,
11174 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011175 (int) pCfg->linkSpeedRssiMid,
11176 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011177 (int) rate_flags,
11178 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011179#endif //LINKSPEED_DEBUG_ENABLED
11180
11181 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11182 {
11183 // we do not want to necessarily report the current speed
11184 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11185 {
11186 // report the max possible speed
11187 rssidx = 0;
11188 }
11189 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11190 {
11191 // report the max possible speed with RSSI scaling
11192 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11193 {
11194 // report the max possible speed
11195 rssidx = 0;
11196 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011197 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 {
11199 // report middle speed
11200 rssidx = 1;
11201 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011202 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11203 {
11204 // report middle speed
11205 rssidx = 2;
11206 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 else
11208 {
11209 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011210 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 }
11212 }
11213 else
11214 {
11215 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11216 hddLog(VOS_TRACE_LEVEL_ERROR,
11217 "%s: Invalid value for reportMaxLinkSpeed: %u",
11218 __func__, pCfg->reportMaxLinkSpeed);
11219 rssidx = 0;
11220 }
11221
11222 maxRate = 0;
11223
11224 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011225 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11226 OperationalRates, &ORLeng))
11227 {
11228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11229 /*To keep GUI happy*/
11230 return 0;
11231 }
11232
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 for (i = 0; i < ORLeng; i++)
11234 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011235 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 {
11237 /* Validate Rate Set */
11238 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11239 {
11240 currentRate = supported_data_rate[j].supported_rate[rssidx];
11241 break;
11242 }
11243 }
11244 /* Update MAX rate */
11245 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11246 }
11247
11248 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011249 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11250 ExtendedRates, &ERLeng))
11251 {
11252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11253 /*To keep GUI happy*/
11254 return 0;
11255 }
11256
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 for (i = 0; i < ERLeng; i++)
11258 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011259 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 {
11261 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11262 {
11263 currentRate = supported_data_rate[j].supported_rate[rssidx];
11264 break;
11265 }
11266 }
11267 /* Update MAX rate */
11268 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11269 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011270 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011271 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011272 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011273 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011274 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011276 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11277 MCSRates, &MCSLeng))
11278 {
11279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11280 /*To keep GUI happy*/
11281 return 0;
11282 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011284#ifdef WLAN_FEATURE_11AC
11285 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011286 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011288 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011289 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011290 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011292 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011294 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011296 maxMCSIdx = 7;
11297 }
11298 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11299 {
11300 maxMCSIdx = 8;
11301 }
11302 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11303 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011304 //VHT20 is supporting 0~8
11305 if (rate_flags & eHAL_TX_RATE_VHT20)
11306 maxMCSIdx = 8;
11307 else
11308 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011309 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011310
11311 if (rate_flags & eHAL_TX_RATE_VHT80)
11312 {
11313 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11314 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11315 }
11316 else if (rate_flags & eHAL_TX_RATE_VHT40)
11317 {
11318 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11319 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11320 }
11321 else if (rate_flags & eHAL_TX_RATE_VHT20)
11322 {
11323 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11324 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11325 }
11326
Leo Chang6f8870f2013-03-26 18:11:36 -070011327 maxSpeedMCS = 1;
11328 if (currentRate > maxRate)
11329 {
11330 maxRate = currentRate;
11331 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011332
Leo Chang6f8870f2013-03-26 18:11:36 -070011333 }
11334 else
11335#endif /* WLAN_FEATURE_11AC */
11336 {
11337 if (rate_flags & eHAL_TX_RATE_HT40)
11338 {
11339 rateFlag |= 1;
11340 }
11341 if (rate_flags & eHAL_TX_RATE_SGI)
11342 {
11343 rateFlag |= 2;
11344 }
11345
11346 for (i = 0; i < MCSLeng; i++)
11347 {
11348 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11349 for (j = 0; j < temp; j++)
11350 {
11351 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11352 {
11353 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11354 break;
11355 }
11356 }
11357 if ((j < temp) && (currentRate > maxRate))
11358 {
11359 maxRate = currentRate;
11360 maxSpeedMCS = 1;
11361 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 }
11364 }
11365 }
11366
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011367 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11368 {
11369 maxRate = myRate;
11370 maxSpeedMCS = 1;
11371 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11372 }
11373
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011375 if (((maxRate < myRate) && (0 == rssidx)) ||
11376 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 {
11378 maxRate = myRate;
11379 if (rate_flags & eHAL_TX_RATE_LEGACY)
11380 {
11381 maxSpeedMCS = 0;
11382 }
11383 else
11384 {
11385 maxSpeedMCS = 1;
11386 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11387 }
11388 }
11389
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011390 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 {
11392 sinfo->txrate.legacy = maxRate;
11393#ifdef LINKSPEED_DEBUG_ENABLED
11394 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11395#endif //LINKSPEED_DEBUG_ENABLED
11396 }
11397 else
11398 {
11399 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011400#ifdef WLAN_FEATURE_11AC
11401 sinfo->txrate.nss = 1;
11402 if (rate_flags & eHAL_TX_RATE_VHT80)
11403 {
11404 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011405 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011406 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011407 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011408 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011409 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11410 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11411 }
11412 else if (rate_flags & eHAL_TX_RATE_VHT20)
11413 {
11414 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11415 }
11416#endif /* WLAN_FEATURE_11AC */
11417 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11418 {
11419 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11420 if (rate_flags & eHAL_TX_RATE_HT40)
11421 {
11422 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11423 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011425 if (rate_flags & eHAL_TX_RATE_SGI)
11426 {
11427 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11428 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011429
Jeff Johnson295189b2012-06-20 16:38:30 -070011430#ifdef LINKSPEED_DEBUG_ENABLED
11431 pr_info("Reporting MCS rate %d flags %x\n",
11432 sinfo->txrate.mcs,
11433 sinfo->txrate.flags );
11434#endif //LINKSPEED_DEBUG_ENABLED
11435 }
11436 }
11437 else
11438 {
11439 // report current rate instead of max rate
11440
11441 if (rate_flags & eHAL_TX_RATE_LEGACY)
11442 {
11443 //provide to the UI in units of 100kbps
11444 sinfo->txrate.legacy = myRate;
11445#ifdef LINKSPEED_DEBUG_ENABLED
11446 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11447#endif //LINKSPEED_DEBUG_ENABLED
11448 }
11449 else
11450 {
11451 //must be MCS
11452 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011453#ifdef WLAN_FEATURE_11AC
11454 sinfo->txrate.nss = 1;
11455 if (rate_flags & eHAL_TX_RATE_VHT80)
11456 {
11457 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11458 }
11459 else
11460#endif /* WLAN_FEATURE_11AC */
11461 {
11462 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11463 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 if (rate_flags & eHAL_TX_RATE_SGI)
11465 {
11466 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11467 }
11468 if (rate_flags & eHAL_TX_RATE_HT40)
11469 {
11470 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11471 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011472#ifdef WLAN_FEATURE_11AC
11473 else if (rate_flags & eHAL_TX_RATE_VHT80)
11474 {
11475 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11476 }
11477#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011478#ifdef LINKSPEED_DEBUG_ENABLED
11479 pr_info("Reporting actual MCS rate %d flags %x\n",
11480 sinfo->txrate.mcs,
11481 sinfo->txrate.flags );
11482#endif //LINKSPEED_DEBUG_ENABLED
11483 }
11484 }
11485 sinfo->filled |= STATION_INFO_TX_BITRATE;
11486
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011487 sinfo->tx_packets =
11488 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11489 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11490 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11491 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11492
11493 sinfo->tx_retries =
11494 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11495 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11496 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11497 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11498
11499 sinfo->tx_failed =
11500 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11501 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11502 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11503 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11504
11505 sinfo->filled |=
11506 STATION_INFO_TX_PACKETS |
11507 STATION_INFO_TX_RETRIES |
11508 STATION_INFO_TX_FAILED;
11509
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011510 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11511 TRACE_CODE_HDD_CFG80211_GET_STA,
11512 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011513 EXIT();
11514 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011515}
11516
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011517static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11518 u8* mac, struct station_info *sinfo)
11519{
11520 int ret;
11521
11522 vos_ssr_protect(__func__);
11523 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11524 vos_ssr_unprotect(__func__);
11525
11526 return ret;
11527}
11528
11529static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011530 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011531{
11532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011533 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011535 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011536
Jeff Johnsone7245742012-09-05 17:12:55 -070011537 ENTER();
11538
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 if (NULL == pAdapter)
11540 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011541 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 return -ENODEV;
11543 }
11544
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11546 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11547 pAdapter->sessionId, timeout));
11548
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011549 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011550 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011552 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11555 "%s: HDD context is not valid", __func__);
11556 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011557 }
11558
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011559 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11560 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11561 (pHddCtx->cfg_ini->fhostArpOffload) &&
11562 (eConnectionState_Associated ==
11563 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11564 {
Amar Singhald53568e2013-09-26 11:03:45 -070011565
11566 hddLog(VOS_TRACE_LEVEL_INFO,
11567 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011568 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011569 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11570 {
11571 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011572 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011573 __func__, vos_status);
11574 }
11575 }
11576
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 /**The get power cmd from the supplicant gets updated by the nl only
11578 *on successful execution of the function call
11579 *we are oppositely mapped w.r.t mode in the driver
11580 **/
11581 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11582
Kiet Lam94fd2922014-06-18 19:12:43 -070011583 if (!mode)
11584 {
11585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11586 "%s: DHCP start indicated through power save", __func__);
11587
11588 pHddCtx->btCoexModeSet = TRUE;
11589 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11590 pAdapter->sessionId);
11591 }
11592 else
11593 {
11594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11595 "%s: DHCP stop indicated through power save", __func__);
11596
11597 pHddCtx->btCoexModeSet = FALSE;
11598 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11599 pAdapter->sessionId);
11600 }
11601
Jeff Johnsone7245742012-09-05 17:12:55 -070011602 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 if (VOS_STATUS_E_FAILURE == vos_status)
11604 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11606 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 return -EINVAL;
11608 }
11609 return 0;
11610}
11611
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011612static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11613 struct net_device *dev, bool mode, int timeout)
11614{
11615 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011616
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011617 vos_ssr_protect(__func__);
11618 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11619 vos_ssr_unprotect(__func__);
11620
11621 return ret;
11622}
Jeff Johnson295189b2012-06-20 16:38:30 -070011623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11624static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11625 struct net_device *netdev,
11626 u8 key_index)
11627{
Jeff Johnsone7245742012-09-05 17:12:55 -070011628 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 return 0;
11630}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011631#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011632
11633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11634static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11635 struct net_device *dev,
11636 struct ieee80211_txq_params *params)
11637{
Jeff Johnsone7245742012-09-05 17:12:55 -070011638 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 return 0;
11640}
11641#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11642static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11643 struct ieee80211_txq_params *params)
11644{
Jeff Johnsone7245742012-09-05 17:12:55 -070011645 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 return 0;
11647}
11648#endif //LINUX_VERSION_CODE
11649
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011650static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 struct net_device *dev, u8 *mac)
11652{
11653 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011654 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011655 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011656 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011657 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011658
Jeff Johnsone7245742012-09-05 17:12:55 -070011659 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011660
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011661 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 return -EINVAL;
11665 }
11666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11668 TRACE_CODE_HDD_CFG80211_DEL_STA,
11669 pAdapter->sessionId, pAdapter->device_mode));
11670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011671 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11672 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011673
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011674 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011675 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11677 "%s: HDD context is not valid", __func__);
11678 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011679 }
11680
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 )
11684 {
11685 if( NULL == mac )
11686 {
11687 v_U16_t i;
11688 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11689 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011690 if ((pAdapter->aStaInfo[i].isUsed) &&
11691 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 {
11693 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11694 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011695 "%s: Delete STA with MAC::"
11696 MAC_ADDRESS_STR,
11697 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011698 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11699 if (VOS_IS_STATUS_SUCCESS(vos_status))
11700 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011701 }
11702 }
11703 }
11704 else
11705 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011706
11707 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11708 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11709 {
11710 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011711 "%s: Skip this DEL STA as this is not used::"
11712 MAC_ADDRESS_STR,
11713 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011714 return -ENOENT;
11715 }
11716
11717 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11718 {
11719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011720 "%s: Skip this DEL STA as deauth is in progress::"
11721 MAC_ADDRESS_STR,
11722 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011723 return -ENOENT;
11724 }
11725
11726 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11727
Jeff Johnson295189b2012-06-20 16:38:30 -070011728 hddLog(VOS_TRACE_LEVEL_INFO,
11729 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011730 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011731 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011732 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011733
11734 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11735 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11736 {
11737 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11738 hddLog(VOS_TRACE_LEVEL_INFO,
11739 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011740 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011741 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011742 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011743 return -ENOENT;
11744 }
11745
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 }
11747 }
11748
11749 EXIT();
11750
11751 return 0;
11752}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011753static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11754 struct net_device *dev, u8 *mac)
11755{
11756 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011757
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011758 vos_ssr_protect(__func__);
11759 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11760 vos_ssr_unprotect(__func__);
11761
11762 return ret;
11763}
11764
11765static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011766 struct net_device *dev, u8 *mac, struct station_parameters *params)
11767{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011769 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011770#ifdef FEATURE_WLAN_TDLS
11771 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011772 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011773
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11775 TRACE_CODE_HDD_CFG80211_ADD_STA,
11776 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011777 mask = params->sta_flags_mask;
11778
11779 set = params->sta_flags_set;
11780
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011781#ifdef WLAN_FEATURE_TDLS_DEBUG
11782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11783 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11784 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11785#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011786
11787 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11788 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011789 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011790 }
11791 }
11792#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011793 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011794}
11795
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011796static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11797 struct net_device *dev, u8 *mac, struct station_parameters *params)
11798{
11799 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011800
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011801 vos_ssr_protect(__func__);
11802 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11803 vos_ssr_unprotect(__func__);
11804
11805 return ret;
11806}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011807#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011808
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011809static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011810 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011811{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011812 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011814 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011815 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011816 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011817 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011818 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011819 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011820 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11821 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011822
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011824 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011827 return -EINVAL;
11828 }
11829
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011830 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11831 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011832
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011833 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11836 "%s: HDD context is not valid", __func__);
11837 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838 }
11839
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011840 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011841 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011842 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011843
Agarwal Ashish3da95242014-05-21 14:57:17 +053011844 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011845 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011846 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011847 pmksa->bssid, WNI_CFG_BSSID_LEN))
11848 {
11849 /* BSSID matched previous entry. Overwrite it. */
11850 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011851 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011853 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011854 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011855 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011857 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011858 dump_bssid(pmksa->bssid);
11859 dump_pmkid(halHandle, pmksa->pmkid);
11860 break;
11861 }
11862 }
11863
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011864 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011865 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011866
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011867 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 {
11869 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011870 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011871 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011872 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011874 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011875 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11876 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011877 dump_bssid(pmksa->bssid);
11878 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011879 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011880 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011881 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11882 pHddStaCtx->PMKIDCacheIndex++;
11883 else
11884 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011885 }
11886
11887
11888 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011889 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11890 __func__, pHddStaCtx->PMKIDCacheIndex );
11891
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011892 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011893 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011894 pHddStaCtx->PMKIDCache,
11895 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011896 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11897 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11898 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011899 return 0;
11900}
11901
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011902static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11903 struct cfg80211_pmksa *pmksa)
11904{
11905 int ret;
11906
11907 vos_ssr_protect(__func__);
11908 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11909 vos_ssr_unprotect(__func__);
11910
11911 return ret;
11912}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011913
Wilson Yang6507c4e2013-10-01 20:11:19 -070011914
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011915static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011916 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011917{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011918 tANI_U32 j=0;
11919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011920 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011921 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011922 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011923 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011924 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011925
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011926 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11927 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011928
11929 /* Validate pAdapter */
11930 if (NULL == pAdapter)
11931 {
11932 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11933 return -EINVAL;
11934 }
11935
11936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11937 status = wlan_hdd_validate_context(pHddCtx);
11938
11939 if (0 != status)
11940 {
11941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11942 "%s: HDD context is not valid", __func__);
11943 return status;
11944 }
11945
11946 /*Retrieve halHandle*/
11947 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011948 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011949
11950 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011951 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011952 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011953 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11954 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011955 }
11956
11957 /*find the matching PMKSA entry from j=0 to (index-1),
11958 * and delete the matched one
11959 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011960 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011961 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011962 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011963 pmksa->bssid,
11964 WNI_CFG_BSSID_LEN))
11965 {
11966 /* BSSID matched entry */
11967 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011968 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011969 {
11970 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011971 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11972 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11973 VOS_MAC_ADDR_SIZE);
11974 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11975 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11976 CSR_RSN_PMKID_SIZE);
11977 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011978
11979 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011980 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11981 VOS_MAC_ADDR_SIZE);
11982 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11983 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011984 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011985 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011986 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011987 if (eHAL_STATUS_SUCCESS !=
11988 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011989 {
11990 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011991 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011992 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011993 }
11994
11995 dump_bssid(pmksa->bssid);
11996 dump_pmkid(halHandle,pmksa->pmkid);
11997
11998 break;
11999 }
12000 }
12001
12002 /* we compare all entries,but cannot find matching entry */
12003 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12004 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012005 hddLog(VOS_TRACE_LEVEL_FATAL,
12006 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12007 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012008 dump_bssid(pmksa->bssid);
12009 dump_pmkid(halHandle, pmksa->pmkid);
12010 return -EINVAL;
12011 }
Wilson Yangef657d32014-01-15 19:19:23 -080012012 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012013}
12014
Wilson Yang6507c4e2013-10-01 20:11:19 -070012015
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012016static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12017 struct cfg80211_pmksa *pmksa)
12018{
12019 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012020
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012021 vos_ssr_protect(__func__);
12022 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12023 vos_ssr_unprotect(__func__);
12024
12025 return ret;
12026
12027}
12028
12029static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012030{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012031 tANI_U32 j=0;
12032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012033 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012034 tHalHandle halHandle;
12035 hdd_context_t *pHddCtx;
12036 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012037 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012038
12039 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12040
12041 /* Validate pAdapter */
12042 if (NULL == pAdapter)
12043 {
12044 hddLog(VOS_TRACE_LEVEL_ERROR,
12045 "%s: Invalid Adapter" ,__func__);
12046 return -EINVAL;
12047 }
12048
12049 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12050 status = wlan_hdd_validate_context(pHddCtx);
12051
12052 if (0 != status)
12053 {
12054 hddLog(VOS_TRACE_LEVEL_ERROR,
12055 "%s: HDD context is not valid", __func__);
12056 return status;
12057 }
12058
12059 /*Retrieve halHandle*/
12060 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012062
12063 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012064 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012065 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012067 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012068 }
12069
12070 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012071 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012072 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012073 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012074 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012075 if (eHAL_STATUS_SUCCESS !=
12076 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012077 {
12078 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12079 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012080 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012081 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012082 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012083 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12084 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12085 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012086
Agarwal Ashish3da95242014-05-21 14:57:17 +053012087 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012088 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012089}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012090
12091static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12092{
12093 int ret;
12094
12095 vos_ssr_protect(__func__);
12096 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12097 vos_ssr_unprotect(__func__);
12098
12099 return ret;
12100}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012101#endif
12102
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012103#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012104static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12105 struct net_device *dev,
12106 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012107{
12108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12109 hdd_station_ctx_t *pHddStaCtx;
12110
12111 if (NULL == pAdapter)
12112 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012114 return -ENODEV;
12115 }
12116
12117 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12118
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12120 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12121 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012122 // Added for debug on reception of Re-assoc Req.
12123 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12124 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012125 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012126 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012127 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012128 }
12129
12130#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012131 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012132 ftie->ie_len);
12133#endif
12134
12135 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012136 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12137 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012138 ftie->ie_len);
12139 return 0;
12140}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012141
12142static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12143 struct net_device *dev,
12144 struct cfg80211_update_ft_ies_params *ftie)
12145{
12146 int ret;
12147
12148 vos_ssr_protect(__func__);
12149 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12150 vos_ssr_unprotect(__func__);
12151
12152 return ret;
12153}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012154#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012155
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012156#ifdef FEATURE_WLAN_SCAN_PNO
12157
12158void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12159 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12160{
12161 int ret;
12162 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12163 hdd_context_t *pHddCtx;
12164
Nirav Shah80830bf2013-12-31 16:35:12 +053012165 ENTER();
12166
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012167 if (NULL == pAdapter)
12168 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012170 "%s: HDD adapter is Null", __func__);
12171 return ;
12172 }
12173
12174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12175 if (NULL == pHddCtx)
12176 {
12177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12178 "%s: HDD context is Null!!!", __func__);
12179 return ;
12180 }
12181
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012182 spin_lock(&pHddCtx->schedScan_lock);
12183 if (TRUE == pHddCtx->isWiphySuspended)
12184 {
12185 pHddCtx->isSchedScanUpdatePending = TRUE;
12186 spin_unlock(&pHddCtx->schedScan_lock);
12187 hddLog(VOS_TRACE_LEVEL_INFO,
12188 "%s: Update cfg80211 scan database after it resume", __func__);
12189 return ;
12190 }
12191 spin_unlock(&pHddCtx->schedScan_lock);
12192
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012193 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12194
12195 if (0 > ret)
12196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12197
12198 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12200 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012201}
12202
12203/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012204 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012205 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012206 */
12207static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12208{
12209 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12210 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012211 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012212 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12213 int status = 0;
12214 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12215
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012216 /* The current firmware design does not allow PNO during any
12217 * active sessions. Hence, determine the active sessions
12218 * and return a failure.
12219 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012220 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12221 {
12222 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012223 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012224
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012225 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12226 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12227 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12228 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12229 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12230 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012231 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012232 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012233 }
12234 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12235 pAdapterNode = pNext;
12236 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012237 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012238}
12239
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012240void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12241{
12242 hdd_adapter_t *pAdapter = callbackContext;
12243 hdd_context_t *pHddCtx;
12244
12245 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12246 {
12247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12248 FL("Invalid adapter or adapter has invalid magic"));
12249 return;
12250 }
12251
12252 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12253 if (0 != wlan_hdd_validate_context(pHddCtx))
12254 {
12255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12256 FL("HDD context is not valid"));
12257 return;
12258 }
12259
12260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12261 FL("PNO enable response status = %d"), status);
12262
12263 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12264 complete(&pAdapter->pno_comp_var);
12265}
12266
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012267/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012268 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12269 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012270 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012271static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012272 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12273{
12274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12275 tpSirPNOScanReq pPnoRequest = NULL;
12276 hdd_context_t *pHddCtx;
12277 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012278 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012279 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12280 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012281 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12282 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012283 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012284
12285 if (NULL == pAdapter)
12286 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012288 "%s: HDD adapter is Null", __func__);
12289 return -ENODEV;
12290 }
12291
12292 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012293 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012294
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012295 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012296 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12298 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012299 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012300 }
12301
12302 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12303 if (NULL == hHal)
12304 {
12305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12306 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012307 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012308 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012309
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012310 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012311 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012312 {
12313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12314 "%s: aborting the existing scan is unsuccessfull", __func__);
12315 return -EBUSY;
12316 }
12317
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012318 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012319 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012321 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012322 return -EBUSY;
12323 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012324
c_hpothu37f21312014-04-09 21:49:54 +053012325 if (TRUE == pHddCtx->isPnoEnable)
12326 {
12327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12328 FL("already PNO is enabled"));
12329 return -EBUSY;
12330 }
12331 pHddCtx->isPnoEnable = TRUE;
12332
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012333 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12334 if (NULL == pPnoRequest)
12335 {
12336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12337 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012338 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012339 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012340 }
12341
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012342 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012343 pPnoRequest->enable = 1; /*Enable PNO */
12344 pPnoRequest->ucNetworksCount = request->n_match_sets;
12345
12346 if (( !pPnoRequest->ucNetworksCount ) ||
12347 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12348 {
12349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012350 "%s: Network input is not correct %d Max Network supported is %d",
12351 __func__, pPnoRequest->ucNetworksCount,
12352 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012353 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012354 goto error;
12355 }
12356
12357 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12358 {
12359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012360 "%s: Incorrect number of channels %d",
12361 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012362 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012363 goto error;
12364 }
12365
12366 /* Framework provides one set of channels(all)
12367 * common for all saved profile */
12368 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12369 channels_allowed, &num_channels_allowed))
12370 {
12371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12372 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012373 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012374 goto error;
12375 }
12376 /* Checking each channel against allowed channel list */
12377 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012378 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012379 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012380 char chList [(request->n_channels*5)+1];
12381 int len;
12382 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012383 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012384 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012385 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012386 if (request->channels[i]->hw_value == channels_allowed[indx])
12387 {
12388 valid_ch[num_ch++] = request->channels[i]->hw_value;
12389 len += snprintf(chList+len, 5, "%d ",
12390 request->channels[i]->hw_value);
12391 break ;
12392 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012393 }
12394 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012395 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12396 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012397
12398 /* Filling per profile params */
12399 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12400 {
12401 pPnoRequest->aNetworks[i].ssId.length =
12402 request->match_sets[i].ssid.ssid_len;
12403
12404 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12405 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12406 {
12407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012408 "%s: SSID Len %d is not correct for network %d",
12409 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012410 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012411 goto error;
12412 }
12413
12414 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12415 request->match_sets[i].ssid.ssid,
12416 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12418 "%s: SSID of network %d is %s ", __func__,
12419 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012420 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12421 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12422 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12423
12424 /*Copying list of valid channel into request */
12425 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12426 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12427
12428 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12429 }
12430
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012432 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012433 if ((0 < request->ie_len) && (NULL != request->ie))
12434 {
12435 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12436 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12437 pPnoRequest->us24GProbeTemplateLen);
12438
12439 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12440 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12441 pPnoRequest->us5GProbeTemplateLen);
12442 }
12443
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012444 /* Driver gets only one time interval which is hardcoded in
12445 * supplicant for 10000ms. Taking power consumption into account 6 timers
12446 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12447 * 80,160,320 secs. And number of scan cycle for each timer
12448 * is configurable through INI param gPNOScanTimerRepeatValue.
12449 * If it is set to 0 only one timer will be used and PNO scan cycle
12450 * will be repeated after each interval specified by supplicant
12451 * till PNO is disabled.
12452 */
12453 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12454 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12455 else
12456 pPnoRequest->scanTimers.ucScanTimersCount =
12457 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12458
12459 tempInterval = (request->interval)/1000;
12460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12461 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12462 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12463 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12464 {
12465 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12466 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12467 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12468 tempInterval *= 2;
12469 }
12470 //Repeat last timer until pno disabled.
12471 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12472
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012473 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012474
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012475 INIT_COMPLETION(pAdapter->pno_comp_var);
12476 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12477 pPnoRequest->callbackContext = pAdapter;
12478 pAdapter->pno_req_status = 0;
12479
Nirav Shah80830bf2013-12-31 16:35:12 +053012480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12481 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12482 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12483 pPnoRequest->scanTimers.ucScanTimersCount);
12484
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012485 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12486 pPnoRequest, pAdapter->sessionId,
12487 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12488 if (eHAL_STATUS_SUCCESS != status)
12489 {
12490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012491 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012492 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012493 goto error;
12494 }
12495
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012496 ret = wait_for_completion_timeout(
12497 &pAdapter->pno_comp_var,
12498 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12499 if (0 >= ret)
12500 {
12501 // Did not receive the response for PNO enable in time.
12502 // Assuming the PNO enable was success.
12503 // Returning error from here, because we timeout, results
12504 // in side effect of Wifi (Wifi Setting) not to work.
12505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12506 FL("Timed out waiting for PNO to be Enabled"));
12507 ret = 0;
12508 goto error;
12509 }
12510
c_hpothu3c986b22014-07-09 14:45:09 +053012511 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012512 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012513 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012514
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012515error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12517 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012518 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012519 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012520 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012521}
12522
12523/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012524 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12525 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012526 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012527static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12528 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12529{
12530 int ret;
12531
12532 vos_ssr_protect(__func__);
12533 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12534 vos_ssr_unprotect(__func__);
12535
12536 return ret;
12537}
12538
12539/*
12540 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12541 * Function to disable PNO
12542 */
12543static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012544 struct net_device *dev)
12545{
12546 eHalStatus status = eHAL_STATUS_FAILURE;
12547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12548 hdd_context_t *pHddCtx;
12549 tHalHandle hHal;
12550 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012551 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012552
12553 ENTER();
12554
12555 if (NULL == pAdapter)
12556 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012558 "%s: HDD adapter is Null", __func__);
12559 return -ENODEV;
12560 }
12561
12562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012563
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012564 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012565 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012567 "%s: HDD context is Null", __func__);
12568 return -ENODEV;
12569 }
12570
12571 /* The return 0 is intentional when isLogpInProgress and
12572 * isLoadUnloadInProgress. We did observe a crash due to a return of
12573 * failure in sched_scan_stop , especially for a case where the unload
12574 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12575 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12576 * success. If it returns a failure , then its next invocation due to the
12577 * clean up of the second interface will have the dev pointer corresponding
12578 * to the first one leading to a crash.
12579 */
12580 if (pHddCtx->isLogpInProgress)
12581 {
12582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12583 "%s: LOGP in Progress. Ignore!!!", __func__);
12584 return ret;
12585 }
12586
Mihir Shete18156292014-03-11 15:38:30 +053012587 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012588 {
12589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12590 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12591 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012592 }
12593
12594 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12595 if (NULL == hHal)
12596 {
12597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12598 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012599 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012600 }
12601
12602 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12603 if (NULL == pPnoRequest)
12604 {
12605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12606 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012607 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012608 }
12609
12610 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12611 pPnoRequest->enable = 0; /* Disable PNO */
12612 pPnoRequest->ucNetworksCount = 0;
12613
12614 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12615 pAdapter->sessionId,
12616 NULL, pAdapter);
12617 if (eHAL_STATUS_SUCCESS != status)
12618 {
12619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12620 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012621 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012622 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012623 }
c_hpothu37f21312014-04-09 21:49:54 +053012624 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012625
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012626error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012628 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012629 vos_mem_free(pPnoRequest);
12630
12631 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012632 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012633}
12634
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012635/*
12636 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12637 * NL interface to disable PNO
12638 */
12639static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12640 struct net_device *dev)
12641{
12642 int ret;
12643
12644 vos_ssr_protect(__func__);
12645 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12646 vos_ssr_unprotect(__func__);
12647
12648 return ret;
12649}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012650#endif /*FEATURE_WLAN_SCAN_PNO*/
12651
12652
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012653#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012654#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012655static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12656 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012657 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12658#else
12659static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12660 u8 *peer, u8 action_code, u8 dialog_token,
12661 u16 status_code, const u8 *buf, size_t len)
12662#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012663{
12664
12665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12666 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012667 u8 peerMac[6];
12668 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012669 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012670 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012671 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012672#if !(TDLS_MGMT_VERSION2)
12673 u32 peer_capability = 0;
12674#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012675 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12678 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12679 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012680 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012681 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012683 "Invalid arguments");
12684 return -EINVAL;
12685 }
12686
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012687 if (pHddCtx->isLogpInProgress)
12688 {
12689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12690 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012691 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012692 return -EBUSY;
12693 }
12694
Hoonki Lee27511902013-03-14 18:19:06 -070012695 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012696 {
Hoonki Lee27511902013-03-14 18:19:06 -070012697 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12698 "%s: TDLS mode is disabled OR not enabled in FW."
12699 MAC_ADDRESS_STR " action %d declined.",
12700 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012701 return -ENOTSUPP;
12702 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012703
Hoonki Lee27511902013-03-14 18:19:06 -070012704 /* other than teardown frame, other mgmt frames are not sent if disabled */
12705 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12706 {
12707 /* if tdls_mode is disabled to respond to peer's request */
12708 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12709 {
12710 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12711 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012712 " TDLS mode is disabled. action %d declined.",
12713 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012714
12715 return -ENOTSUPP;
12716 }
12717 }
12718
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012719 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12720 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012721 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012722 {
12723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012724 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012725 " TDLS setup is ongoing. action %d declined.",
12726 __func__, MAC_ADDR_ARRAY(peer), action_code);
12727 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012728 }
12729 }
12730
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012731 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12732 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012733 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012734 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12735 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012736 {
12737 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12738 we return error code at 'add_station()'. Hence we have this
12739 check again in addtion to add_station().
12740 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012741 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012742 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12744 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012745 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12746 __func__, MAC_ADDR_ARRAY(peer), action_code,
12747 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012748 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012749 }
12750 else
12751 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012752 /* maximum reached. tweak to send error code to peer and return
12753 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012754 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12756 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012757 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12758 __func__, MAC_ADDR_ARRAY(peer), status_code,
12759 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012760 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012761 /* fall through to send setup resp with failure status
12762 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012763 }
12764 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012765 else
12766 {
12767 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012768 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012769 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012770 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012772 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12773 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012774 return -EPERM;
12775 }
12776 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012777 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012778 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012779
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012780#ifdef WLAN_FEATURE_TDLS_DEBUG
12781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012782 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012783 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12784 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012785#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012786
Hoonki Leea34dd892013-02-05 22:56:02 -080012787 /*Except teardown responder will not be used so just make 0*/
12788 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012789 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012790 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012791
12792 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012793 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012794
12795 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12796 responder = pTdlsPeer->is_responder;
12797 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012798 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012800 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012801 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12802 dialog_token, status_code, len);
12803 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012804 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012805 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012806
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012807 /* For explicit trigger of DIS_REQ come out of BMPS for
12808 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012809 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012810 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12811 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012812 {
12813 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12814 {
12815 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012816 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012817 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12818 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012819 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12820 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012821 }
12822
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012823 /* make sure doesn't call send_mgmt() while it is pending */
12824 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12825 {
12826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012827 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012828 __func__, MAC_ADDR_ARRAY(peer), action_code);
12829 return -EBUSY;
12830 }
12831
12832 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012833 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12834
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012835 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012836 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012837
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012838 if (VOS_STATUS_SUCCESS != status)
12839 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12841 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012842 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012843 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012844 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012845 }
12846
Hoonki Leed37cbb32013-04-20 00:31:14 -070012847 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12848 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12849
12850 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012851 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012853 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012854 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012855 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012856
12857 if (pHddCtx->isLogpInProgress)
12858 {
12859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12860 "%s: LOGP in Progress. Ignore!!!", __func__);
12861 return -EAGAIN;
12862 }
12863
Hoonki Leed37cbb32013-04-20 00:31:14 -070012864 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012865 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012866 }
12867
Gopichand Nakkala05922802013-03-14 12:23:19 -070012868 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012869 {
12870 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012871 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012872 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012873
Hoonki Leea34dd892013-02-05 22:56:02 -080012874 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12875 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012876 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012877 }
12878 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12879 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012880 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012881 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012882
12883 return 0;
12884}
12885
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012886static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012887 u8 *peer, enum nl80211_tdls_operation oper)
12888{
12889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12890 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012891 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012892 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012893
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12895 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12896 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012897 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012898 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012900 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012901 return -EINVAL;
12902 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012903
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012904 status = wlan_hdd_validate_context(pHddCtx);
12905
12906 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012907 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12909 "%s: HDD context is not valid", __func__);
12910 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012911 }
12912
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012913
12914 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012915 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012916 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012918 "TDLS Disabled in INI OR not enabled in FW. "
12919 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012920 return -ENOTSUPP;
12921 }
12922
12923 switch (oper) {
12924 case NL80211_TDLS_ENABLE_LINK:
12925 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012926 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012927 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012928 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012929
Sunil Dutt41de4e22013-11-14 18:09:02 +053012930 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12931
12932 if ( NULL == pTdlsPeer ) {
12933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12934 " (oper %d) not exsting. ignored",
12935 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12936 return -EINVAL;
12937 }
12938
12939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12940 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12941 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12942 "NL80211_TDLS_ENABLE_LINK");
12943
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012944 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12945 {
12946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12947 MAC_ADDRESS_STR " failed",
12948 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12949 return -EINVAL;
12950 }
12951
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012952 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012953 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012954 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012955
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012956 if (0 != wlan_hdd_tdls_get_link_establish_params(
12957 pAdapter, peer,&tdlsLinkEstablishParams)) {
12958 return -EINVAL;
12959 }
12960 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012961
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012962 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12963 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12964 /* Send TDLS peer UAPSD capabilities to the firmware and
12965 * register with the TL on after the response for this operation
12966 * is received .
12967 */
12968 ret = wait_for_completion_interruptible_timeout(
12969 &pAdapter->tdls_link_establish_req_comp,
12970 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12971 if (ret <= 0)
12972 {
12973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12974 "%s: Link Establish Request Faled Status %ld",
12975 __func__, ret);
12976 return -EINVAL;
12977 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012978 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012979 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012980 /* Mark TDLS client Authenticated .*/
12981 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12982 pTdlsPeer->staId,
12983 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012984 if (VOS_STATUS_SUCCESS == status)
12985 {
Hoonki Lee14621352013-04-16 17:51:19 -070012986 if (pTdlsPeer->is_responder == 0)
12987 {
12988 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12989
12990 wlan_hdd_tdls_timer_restart(pAdapter,
12991 &pTdlsPeer->initiatorWaitTimeoutTimer,
12992 WAIT_TIME_TDLS_INITIATOR);
12993 /* suspend initiator TX until it receives direct packet from the
12994 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12995 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12996 &staId, NULL);
12997 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012998 wlan_hdd_tdls_increment_peer_count(pAdapter);
12999 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013000 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013001
13002 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013003 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13004 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013005 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013006 int ac;
13007 uint8 ucAc[4] = { WLANTL_AC_VO,
13008 WLANTL_AC_VI,
13009 WLANTL_AC_BK,
13010 WLANTL_AC_BE };
13011 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13012 for(ac=0; ac < 4; ac++)
13013 {
13014 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13015 pTdlsPeer->staId, ucAc[ac],
13016 tlTid[ac], tlTid[ac], 0, 0,
13017 WLANTL_BI_DIR );
13018 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013019 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013020 }
13021
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013022 }
13023 break;
13024 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013025 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013026 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13027
13028 if ( NULL == pTdlsPeer ) {
13029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13030 " (oper %d) not exsting. ignored",
13031 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13032 return -EINVAL;
13033 }
13034
13035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13036 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13037 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13038 "NL80211_TDLS_DISABLE_LINK");
13039
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013040 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013041 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013042 long status;
13043
13044 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13045
Lee Hoonkic1262f22013-01-24 21:59:00 -080013046 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13047 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013048
13049 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13050 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13051 if (status <= 0)
13052 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013053 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13055 "%s: Del station failed status %ld",
13056 __func__, status);
13057 return -EPERM;
13058 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013059 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013060 }
13061 else
13062 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13064 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013065 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013066 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013067 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013068 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013069 {
13070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13071 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13072 __func__, MAC_ADDR_ARRAY(peer));
13073
13074 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13075 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13076
13077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13078 " %s TDLS External control and Implicit Trigger not enabled ",
13079 __func__);
13080 return -ENOTSUPP;
13081 }
13082
Sunil Dutt41de4e22013-11-14 18:09:02 +053013083
13084 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13085
13086 if ( NULL == pTdlsPeer ) {
13087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13088 " peer not exsting",
13089 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013090 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013091 }
13092 else {
13093 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13094 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13095 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013096
13097 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13098 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013099 break;
13100 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013101 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013102 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013103 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13105 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13106 __func__, MAC_ADDR_ARRAY(peer));
13107
13108 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13109 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13110
13111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13112 " %s TDLS External control and Implicit Trigger not enabled ",
13113 __func__);
13114 return -ENOTSUPP;
13115 }
13116
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013117 /* To cater the requirement of establishing the TDLS link
13118 * irrespective of the data traffic , get an entry of TDLS peer.
13119 */
13120 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13121 if (pTdlsPeer == NULL) {
13122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13123 "%s: peer " MAC_ADDRESS_STR " not existing",
13124 __func__, MAC_ADDR_ARRAY(peer));
13125 return -EINVAL;
13126 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013127
13128 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13129
13130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13131 " %s TDLS Add Force Peer Failed",
13132 __func__);
13133 return -EINVAL;
13134 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013135 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013136 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013137 case NL80211_TDLS_DISCOVERY_REQ:
13138 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13140 "%s: We don't support in-driver setup/teardown/discovery "
13141 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013142 return -ENOTSUPP;
13143 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13145 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013146 return -ENOTSUPP;
13147 }
13148 return 0;
13149}
Chilam NG571c65a2013-01-19 12:27:36 +053013150
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013151static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13152 u8 *peer, enum nl80211_tdls_operation oper)
13153{
13154 int ret;
13155
13156 vos_ssr_protect(__func__);
13157 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13158 vos_ssr_unprotect(__func__);
13159
13160 return ret;
13161}
13162
Chilam NG571c65a2013-01-19 12:27:36 +053013163int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13164 struct net_device *dev, u8 *peer)
13165{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013166 hddLog(VOS_TRACE_LEVEL_INFO,
13167 "tdls send discover req: "MAC_ADDRESS_STR,
13168 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013169
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013170#if TDLS_MGMT_VERSION2
13171 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13172 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13173#else
Chilam NG571c65a2013-01-19 12:27:36 +053013174 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13175 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013176#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013177}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013178#endif
13179
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013180#ifdef WLAN_FEATURE_GTK_OFFLOAD
13181/*
13182 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13183 * Callback rountine called upon receiving response for
13184 * get offload info
13185 */
13186void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13187 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13188{
13189
13190 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013191 tANI_U8 tempReplayCounter[8];
13192 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013193
13194 ENTER();
13195
13196 if (NULL == pAdapter)
13197 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013199 "%s: HDD adapter is Null", __func__);
13200 return ;
13201 }
13202
13203 if (NULL == pGtkOffloadGetInfoRsp)
13204 {
13205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13206 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13207 return ;
13208 }
13209
13210 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13211 {
13212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13213 "%s: wlan Failed to get replay counter value",
13214 __func__);
13215 return ;
13216 }
13217
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13219 /* Update replay counter */
13220 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13221 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13222
13223 {
13224 /* changing from little to big endian since supplicant
13225 * works on big endian format
13226 */
13227 int i;
13228 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13229
13230 for (i = 0; i < 8; i++)
13231 {
13232 tempReplayCounter[7-i] = (tANI_U8)p[i];
13233 }
13234 }
13235
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013236 /* Update replay counter to NL */
13237 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013238 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013239}
13240
13241/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013242 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013243 * This function is used to offload GTK rekeying job to the firmware.
13244 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013245int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013246 struct cfg80211_gtk_rekey_data *data)
13247{
13248 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13249 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13250 hdd_station_ctx_t *pHddStaCtx;
13251 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013252 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013253 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013254 eHalStatus status = eHAL_STATUS_FAILURE;
13255
13256 ENTER();
13257
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013258
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013259 if (NULL == pAdapter)
13260 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013262 "%s: HDD adapter is Null", __func__);
13263 return -ENODEV;
13264 }
13265
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013266 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13267 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13268 pAdapter->sessionId, pAdapter->device_mode));
13269
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013270 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013271
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013272 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013273 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13275 "%s: HDD context is not valid", __func__);
13276 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013277 }
13278
13279 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13280 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13281 if (NULL == hHal)
13282 {
13283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13284 "%s: HAL context is Null!!!", __func__);
13285 return -EAGAIN;
13286 }
13287
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013288 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13289 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13290 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13291 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013292 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013293 {
13294 /* changing from big to little endian since driver
13295 * works on little endian format
13296 */
13297 tANI_U8 *p =
13298 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13299 int i;
13300
13301 for (i = 0; i < 8; i++)
13302 {
13303 p[7-i] = data->replay_ctr[i];
13304 }
13305 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013306
13307 if (TRUE == pHddCtx->hdd_wlan_suspended)
13308 {
13309 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013310 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13311 sizeof (tSirGtkOffloadParams));
13312 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013313 pAdapter->sessionId);
13314
13315 if (eHAL_STATUS_SUCCESS != status)
13316 {
13317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13318 "%s: sme_SetGTKOffload failed, returned %d",
13319 __func__, status);
13320 return status;
13321 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13323 "%s: sme_SetGTKOffload successfull", __func__);
13324 }
13325 else
13326 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13328 "%s: wlan not suspended GTKOffload request is stored",
13329 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013330 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013331
13332 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013333}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013334
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013335int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13336 struct cfg80211_gtk_rekey_data *data)
13337{
13338 int ret;
13339
13340 vos_ssr_protect(__func__);
13341 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13342 vos_ssr_unprotect(__func__);
13343
13344 return ret;
13345}
13346#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013347/*
13348 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13349 * This function is used to set access control policy
13350 */
13351static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13352 struct net_device *dev, const struct cfg80211_acl_data *params)
13353{
13354 int i;
13355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13356 hdd_hostapd_state_t *pHostapdState;
13357 tsap_Config_t *pConfig;
13358 v_CONTEXT_t pVosContext = NULL;
13359 hdd_context_t *pHddCtx;
13360 int status;
13361
13362 ENTER();
13363
13364 if (NULL == pAdapter)
13365 {
13366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13367 "%s: HDD adapter is Null", __func__);
13368 return -ENODEV;
13369 }
13370
13371 if (NULL == params)
13372 {
13373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13374 "%s: params is Null", __func__);
13375 return -EINVAL;
13376 }
13377
13378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13379 status = wlan_hdd_validate_context(pHddCtx);
13380
13381 if (0 != status)
13382 {
13383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13384 "%s: HDD context is not valid", __func__);
13385 return status;
13386 }
13387
13388 pVosContext = pHddCtx->pvosContext;
13389 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13390
13391 if (NULL == pHostapdState)
13392 {
13393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13394 "%s: pHostapdState is Null", __func__);
13395 return -EINVAL;
13396 }
13397
13398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13399 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13400
13401 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13402 {
13403 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13404
13405 /* default value */
13406 pConfig->num_accept_mac = 0;
13407 pConfig->num_deny_mac = 0;
13408
13409 /**
13410 * access control policy
13411 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13412 * listed in hostapd.deny file.
13413 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13414 * listed in hostapd.accept file.
13415 */
13416 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13417 {
13418 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13419 }
13420 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13421 {
13422 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13423 }
13424 else
13425 {
13426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13427 "%s:Acl Policy : %d is not supported",
13428 __func__, params->acl_policy);
13429 return -ENOTSUPP;
13430 }
13431
13432 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13433 {
13434 pConfig->num_accept_mac = params->n_acl_entries;
13435 for (i = 0; i < params->n_acl_entries; i++)
13436 {
13437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13438 "** Add ACL MAC entry %i in WhiletList :"
13439 MAC_ADDRESS_STR, i,
13440 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13441
13442 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13443 sizeof(qcmacaddr));
13444 }
13445 }
13446 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13447 {
13448 pConfig->num_deny_mac = params->n_acl_entries;
13449 for (i = 0; i < params->n_acl_entries; i++)
13450 {
13451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13452 "** Add ACL MAC entry %i in BlackList :"
13453 MAC_ADDRESS_STR, i,
13454 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13455
13456 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13457 sizeof(qcmacaddr));
13458 }
13459 }
13460
13461 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13462 {
13463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13464 "%s: SAP Set Mac Acl fail", __func__);
13465 return -EINVAL;
13466 }
13467 }
13468 else
13469 {
13470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013471 "%s: Invalid device_mode = %s (%d)",
13472 __func__, hdd_device_modetoString(pAdapter->device_mode),
13473 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013474 return -EINVAL;
13475 }
13476
13477 return 0;
13478}
13479
Leo Chang9056f462013-08-01 19:21:11 -070013480#ifdef WLAN_NL80211_TESTMODE
13481#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013482void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013483(
13484 void *pAdapter,
13485 void *indCont
13486)
13487{
Leo Changd9df8aa2013-09-26 13:32:26 -070013488 tSirLPHBInd *lphbInd;
13489 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013490 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013491
13492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013493 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013494
c_hpothu73f35e62014-04-18 13:40:08 +053013495 if (pAdapter == NULL)
13496 {
13497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13498 "%s: pAdapter is NULL\n",__func__);
13499 return;
13500 }
13501
Leo Chang9056f462013-08-01 19:21:11 -070013502 if (NULL == indCont)
13503 {
13504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013505 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013506 return;
13507 }
13508
c_hpothu73f35e62014-04-18 13:40:08 +053013509 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013510 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013511 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013512 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013513 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013514 GFP_ATOMIC);
13515 if (!skb)
13516 {
13517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13518 "LPHB timeout, NL buffer alloc fail");
13519 return;
13520 }
13521
Leo Changac3ba772013-10-07 09:47:04 -070013522 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013523 {
13524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13525 "WLAN_HDD_TM_ATTR_CMD put fail");
13526 goto nla_put_failure;
13527 }
Leo Changac3ba772013-10-07 09:47:04 -070013528 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013529 {
13530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13531 "WLAN_HDD_TM_ATTR_TYPE put fail");
13532 goto nla_put_failure;
13533 }
Leo Changac3ba772013-10-07 09:47:04 -070013534 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013535 sizeof(tSirLPHBInd), lphbInd))
13536 {
13537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13538 "WLAN_HDD_TM_ATTR_DATA put fail");
13539 goto nla_put_failure;
13540 }
Leo Chang9056f462013-08-01 19:21:11 -070013541 cfg80211_testmode_event(skb, GFP_ATOMIC);
13542 return;
13543
13544nla_put_failure:
13545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13546 "NLA Put fail");
13547 kfree_skb(skb);
13548
13549 return;
13550}
13551#endif /* FEATURE_WLAN_LPHB */
13552
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013553static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013554{
13555 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13556 int err = 0;
13557#ifdef FEATURE_WLAN_LPHB
13558 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013559 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013560#endif /* FEATURE_WLAN_LPHB */
13561
13562 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13563 if (err)
13564 {
13565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13566 "%s Testmode INV ATTR", __func__);
13567 return err;
13568 }
13569
13570 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13571 {
13572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13573 "%s Testmode INV CMD", __func__);
13574 return -EINVAL;
13575 }
13576
13577 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13578 {
13579#ifdef FEATURE_WLAN_LPHB
13580 /* Low Power Heartbeat configuration request */
13581 case WLAN_HDD_TM_CMD_WLAN_HB:
13582 {
13583 int buf_len;
13584 void *buf;
13585 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013586 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013587
13588 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13589 {
13590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13591 "%s Testmode INV DATA", __func__);
13592 return -EINVAL;
13593 }
13594
13595 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13596 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013597
13598 hb_params_temp =(tSirLPHBReq *)buf;
13599 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13600 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13601 return -EINVAL;
13602
Leo Chang9056f462013-08-01 19:21:11 -070013603 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13604 if (NULL == hb_params)
13605 {
13606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13607 "%s Request Buffer Alloc Fail", __func__);
13608 return -EINVAL;
13609 }
13610
13611 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013612 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13613 hb_params,
13614 wlan_hdd_cfg80211_lphb_ind_handler);
13615 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013616 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13618 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013619 vos_mem_free(hb_params);
13620 }
Leo Chang9056f462013-08-01 19:21:11 -070013621 return 0;
13622 }
13623#endif /* FEATURE_WLAN_LPHB */
13624 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13626 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013627 return -EOPNOTSUPP;
13628 }
13629
13630 return err;
13631}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013632
13633static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13634{
13635 int ret;
13636
13637 vos_ssr_protect(__func__);
13638 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13639 vos_ssr_unprotect(__func__);
13640
13641 return ret;
13642}
Leo Chang9056f462013-08-01 19:21:11 -070013643#endif /* CONFIG_NL80211_TESTMODE */
13644
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013645static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013646 struct net_device *dev,
13647 int idx, struct survey_info *survey)
13648{
13649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13650 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013651 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013652 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013653 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013654 v_S7_t snr,rssi;
13655 int status, i, j, filled = 0;
13656
13657 ENTER();
13658
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013659 if (NULL == pAdapter)
13660 {
13661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13662 "%s: HDD adapter is Null", __func__);
13663 return -ENODEV;
13664 }
13665
13666 if (NULL == wiphy)
13667 {
13668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13669 "%s: wiphy is Null", __func__);
13670 return -ENODEV;
13671 }
13672
13673 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13674 status = wlan_hdd_validate_context(pHddCtx);
13675
13676 if (0 != status)
13677 {
13678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13679 "%s: HDD context is not valid", __func__);
13680 return status;
13681 }
13682
Mihir Sheted9072e02013-08-21 17:02:29 +053013683 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13684
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013685 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013686 0 != pAdapter->survey_idx ||
13687 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013688 {
13689 /* The survey dump ops when implemented completely is expected to
13690 * return a survey of all channels and the ops is called by the
13691 * kernel with incremental values of the argument 'idx' till it
13692 * returns -ENONET. But we can only support the survey for the
13693 * operating channel for now. survey_idx is used to track
13694 * that the ops is called only once and then return -ENONET for
13695 * the next iteration
13696 */
13697 pAdapter->survey_idx = 0;
13698 return -ENONET;
13699 }
13700
13701 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13702
13703 wlan_hdd_get_snr(pAdapter, &snr);
13704 wlan_hdd_get_rssi(pAdapter, &rssi);
13705
13706 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13707 hdd_wlan_get_freq(channel, &freq);
13708
13709
13710 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13711 {
13712 if (NULL == wiphy->bands[i])
13713 {
13714 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13715 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13716 continue;
13717 }
13718
13719 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13720 {
13721 struct ieee80211_supported_band *band = wiphy->bands[i];
13722
13723 if (band->channels[j].center_freq == (v_U16_t)freq)
13724 {
13725 survey->channel = &band->channels[j];
13726 /* The Rx BDs contain SNR values in dB for the received frames
13727 * while the supplicant expects noise. So we calculate and
13728 * return the value of noise (dBm)
13729 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13730 */
13731 survey->noise = rssi - snr;
13732 survey->filled = SURVEY_INFO_NOISE_DBM;
13733 filled = 1;
13734 }
13735 }
13736 }
13737
13738 if (filled)
13739 pAdapter->survey_idx = 1;
13740 else
13741 {
13742 pAdapter->survey_idx = 0;
13743 return -ENONET;
13744 }
13745
13746 return 0;
13747}
13748
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013749static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13750 struct net_device *dev,
13751 int idx, struct survey_info *survey)
13752{
13753 int ret;
13754
13755 vos_ssr_protect(__func__);
13756 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13757 vos_ssr_unprotect(__func__);
13758
13759 return ret;
13760}
13761
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013762/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013763 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013764 * this is called when cfg80211 driver resume
13765 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13766 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013767int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013768{
13769 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13770 hdd_adapter_t *pAdapter;
13771 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13772 VOS_STATUS status = VOS_STATUS_SUCCESS;
13773
13774 ENTER();
13775
13776 if ( NULL == pHddCtx )
13777 {
13778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13779 "%s: HddCtx validation failed", __func__);
13780 return 0;
13781 }
13782
13783 if (pHddCtx->isLogpInProgress)
13784 {
13785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13786 "%s: LOGP in Progress. Ignore!!!", __func__);
13787 return 0;
13788 }
13789
Mihir Shete18156292014-03-11 15:38:30 +053013790 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013791 {
13792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13793 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13794 return 0;
13795 }
13796
13797 spin_lock(&pHddCtx->schedScan_lock);
13798 pHddCtx->isWiphySuspended = FALSE;
13799 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13800 {
13801 spin_unlock(&pHddCtx->schedScan_lock);
13802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13803 "%s: Return resume is not due to PNO indication", __func__);
13804 return 0;
13805 }
13806 // Reset flag to avoid updatating cfg80211 data old results again
13807 pHddCtx->isSchedScanUpdatePending = FALSE;
13808 spin_unlock(&pHddCtx->schedScan_lock);
13809
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013810
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013811 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13812
13813 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13814 {
13815 pAdapter = pAdapterNode->pAdapter;
13816 if ( (NULL != pAdapter) &&
13817 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13818 {
13819 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013820 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13822 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013823 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013824 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013825 {
13826 /* Acquire wakelock to handle the case where APP's tries to
13827 * suspend immediately after updating the scan results. Whis
13828 * results in app's is in suspended state and not able to
13829 * process the connect request to AP
13830 */
13831 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013832 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013833 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013834
13835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13836 "%s : cfg80211 scan result database updated", __func__);
13837
13838 return 0;
13839
13840 }
13841 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13842 pAdapterNode = pNext;
13843 }
13844
13845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13846 "%s: Failed to find Adapter", __func__);
13847 return 0;
13848}
13849
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013850int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13851{
13852 int ret;
13853
13854 vos_ssr_protect(__func__);
13855 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13856 vos_ssr_unprotect(__func__);
13857
13858 return ret;
13859}
13860
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013861/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013862 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013863 * this is called when cfg80211 driver suspends
13864 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013865int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013866 struct cfg80211_wowlan *wow)
13867{
13868 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13869
13870 ENTER();
13871 if (NULL == pHddCtx)
13872 {
13873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13874 "%s: HddCtx validation failed", __func__);
13875 return 0;
13876 }
13877
13878 pHddCtx->isWiphySuspended = TRUE;
13879
13880 EXIT();
13881
13882 return 0;
13883}
13884
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013885int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13886 struct cfg80211_wowlan *wow)
13887{
13888 int ret;
13889
13890 vos_ssr_protect(__func__);
13891 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13892 vos_ssr_unprotect(__func__);
13893
13894 return ret;
13895}
Jeff Johnson295189b2012-06-20 16:38:30 -070013896/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013898{
13899 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13900 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13901 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13902 .change_station = wlan_hdd_change_station,
13903#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13904 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13905 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13906 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013907#else
13908 .start_ap = wlan_hdd_cfg80211_start_ap,
13909 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13910 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013911#endif
13912 .change_bss = wlan_hdd_cfg80211_change_bss,
13913 .add_key = wlan_hdd_cfg80211_add_key,
13914 .get_key = wlan_hdd_cfg80211_get_key,
13915 .del_key = wlan_hdd_cfg80211_del_key,
13916 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013917#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013919#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013920 .scan = wlan_hdd_cfg80211_scan,
13921 .connect = wlan_hdd_cfg80211_connect,
13922 .disconnect = wlan_hdd_cfg80211_disconnect,
13923 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13924 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13925 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13926 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13927 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13929 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013930 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13932 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13933 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13934 .set_txq_params = wlan_hdd_set_txq_params,
13935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 .get_station = wlan_hdd_cfg80211_get_station,
13937 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13938 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013939 .add_station = wlan_hdd_cfg80211_add_station,
13940#ifdef FEATURE_WLAN_LFR
13941 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13942 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13943 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13944#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013945#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13946 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13947#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013948#ifdef FEATURE_WLAN_TDLS
13949 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13950 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13951#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013952#ifdef WLAN_FEATURE_GTK_OFFLOAD
13953 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13954#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013955#ifdef FEATURE_WLAN_SCAN_PNO
13956 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13957 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13958#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013959 .resume = wlan_hdd_cfg80211_resume_wlan,
13960 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013961 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013962#ifdef WLAN_NL80211_TESTMODE
13963 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13964#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013965 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013966};
13967