blob: df94de72b24d816883ad2122f7035fada2a46468 [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];
1499 tpSirLLStatsSetReq pLinkLayerStatsSetReq;
1500 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 }
1518
1519 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1520 (struct nlattr *)data,
1521 data_len, qca_wlan_vendor_ll_set_policy))
1522 {
1523 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1524 return -EINVAL;
1525 }
1526 if (!tb_vendor
1527 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1528 {
1529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1530 return -EINVAL;
1531 }
1532 if (!tb_vendor[
1533 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1536 return -EINVAL;
1537 }
1538 pLinkLayerStatsSetReq = vos_mem_malloc(sizeof(tSirLLStatsSetReq));
1539 if (NULL == pLinkLayerStatsSetReq)
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL(" Unable to allocate memory to pLinkLayerStatsSetReq") );
1543 return -ENOMEM;
1544 }
1545 // Shall take the request Id if the Upper layers pass. 1 For now.
1546 pLinkLayerStatsSetReq->reqId = 1;
1547
1548 pLinkLayerStatsSetReq->mpduSizeThreshold =
1549 nla_get_u32(
1550 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1551
1552 pLinkLayerStatsSetReq->aggressiveStatisticsGathering =
1553 nla_get_u32(
1554 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1555
1556 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1557 * Hence the interface staId start from 1. Hence the staId matching the
1558 * interface in the firmware is sessionId + 1.
1559 */
1560 pLinkLayerStatsSetReq->staId = pAdapter->sessionId + 1;
1561
1562
1563 hddLog(VOS_TRACE_LEVEL_INFO,
1564 "LL_STATS_SET reqId = %d",
1565 pLinkLayerStatsSetReq->reqId);
1566 hddLog(VOS_TRACE_LEVEL_INFO,
1567 "LL_STATS_SET staId = %d", pLinkLayerStatsSetReq->staId);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS_SET mpduSizeThreshold = %d",
1570 pLinkLayerStatsSetReq->mpduSizeThreshold);
1571 hddLog(VOS_TRACE_LEVEL_INFO,
1572 "LL_STATS_SET aggressive Statistics Gathering = %d",
1573 pLinkLayerStatsSetReq->aggressiveStatisticsGathering);
1574
1575 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1576 pHddCtx->hHal,
1577 pAdapter->sessionId,
1578 hdd_link_layer_stats_ind_callback,
1579 pAdapter))
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1582 "sme_SetLinkLayerStatsIndCB Failed", __func__);
1583 vos_mem_free(pLinkLayerStatsSetReq);
1584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
1588 pLinkLayerStatsSetReq))
1589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
1592 vos_mem_free(pLinkLayerStatsSetReq);
1593 return -EINVAL;
1594 }
1595
1596 pAdapter->isLinkLayerStatsSet = 1;
1597
1598 return 0;
1599}
1600
1601const struct
1602nla_policy
1603qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1604{
1605 /* Unsigned 32bit value provided by the caller issuing the GET stats
1606 * command. When reporting
1607 * the stats results, the driver uses the same value to indicate
1608 * which GET request the results
1609 * correspond to.
1610 */
1611 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1612
1613 /* Unsigned 32bit value . bit mask to identify what statistics are
1614 requested for retrieval */
1615 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1616};
1617
1618static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1619 struct wireless_dev *wdev,
1620 void *data,
1621 int data_len)
1622{
1623 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1624 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
1625 tpSirLLStatsGetReq pLinkLayerStatsGetReq;
1626 struct net_device *dev = wdev->netdev;
1627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1628 int status;
1629
1630 status = wlan_hdd_validate_context(pHddCtx);
1631 if (0 != status)
1632 {
1633 hddLog(VOS_TRACE_LEVEL_ERROR,
1634 FL("HDD context is not valid"));
1635 return -EINVAL ;
1636 }
1637
1638 if (NULL == pAdapter)
1639 {
1640 hddLog(VOS_TRACE_LEVEL_FATAL,
1641 "%s: HDD adapter is Null", __func__);
1642 return -ENODEV;
1643 }
1644
1645 if (!pAdapter->isLinkLayerStatsSet)
1646 {
1647 hddLog(VOS_TRACE_LEVEL_FATAL,
1648 "%s: isLinkLayerStatsSet : %d",
1649 __func__, pAdapter->isLinkLayerStatsSet);
1650 return -EINVAL;
1651 }
1652
1653 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1654 (struct nlattr *)data,
1655 data_len, qca_wlan_vendor_ll_get_policy))
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1658 return -EINVAL;
1659 }
1660
1661 if (!tb_vendor
1662 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1663 {
1664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1665 return -EINVAL;
1666 }
1667
1668 if (!tb_vendor
1669 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1670 {
1671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1672 return -EINVAL;
1673 }
1674
1675 pLinkLayerStatsGetReq = vos_mem_malloc(sizeof(tSirLLStatsGetReq));
1676
1677 if (NULL == pLinkLayerStatsGetReq)
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("Unable to allocate memory to pLinkLayerStatsGetReq"));
1681 return -ENOMEM;
1682 }
1683
1684 pLinkLayerStatsGetReq->reqId =
1685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
1687 pLinkLayerStatsGetReq->paramIdMask =
1688 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 */
1695 pLinkLayerStatsGetReq->staId = pAdapter->sessionId + 1;
1696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
1698 "LL_STATS_GET reqId = %d", pLinkLayerStatsGetReq->reqId);
1699 hddLog(VOS_TRACE_LEVEL_INFO,
1700 "LL_STATS_GET staId = %d", pLinkLayerStatsGetReq->staId);
1701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
1703 pLinkLayerStatsGetReq->paramIdMask);
1704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
1706 pLinkLayerStatsGetReq))
1707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
1710 vos_mem_free(pLinkLayerStatsGetReq);
1711 return -EINVAL;
1712 }
1713 return 0;
1714}
1715
1716const struct
1717nla_policy
1718qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1719{
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1724};
1725
1726static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1727 struct wireless_dev *wdev,
1728 void *data,
1729 int data_len)
1730{
1731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1732 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
1733 tpSirLLStatsClearReq pLinkLayerStatsClearReq;
1734 struct net_device *dev = wdev->netdev;
1735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1736 u32 statsClearReqMask;
1737 u8 stopReq;
1738 int status;
1739
1740 status = wlan_hdd_validate_context(pHddCtx);
1741 if (0 != status)
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR,
1744 FL("HDD context is not valid"));
1745 return -EINVAL;
1746 }
1747
1748 if (NULL == pAdapter)
1749 {
1750 hddLog(VOS_TRACE_LEVEL_FATAL,
1751 "%s: HDD adapter is Null", __func__);
1752 return -ENODEV;
1753 }
1754
1755 if (!pAdapter->isLinkLayerStatsSet)
1756 {
1757 hddLog(VOS_TRACE_LEVEL_FATAL,
1758 "%s: isLinkLayerStatsSet : %d",
1759 __func__, pAdapter->isLinkLayerStatsSet);
1760 return -EINVAL;
1761 }
1762
1763 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1764 (struct nlattr *)data,
1765 data_len, qca_wlan_vendor_ll_clr_policy))
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1768 return -EINVAL;
1769 }
1770
1771 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1772
1773 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1774 {
1775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1776 return -EINVAL;
1777
1778 }
1779
1780 pLinkLayerStatsClearReq = vos_mem_malloc(sizeof(tSirLLStatsClearReq));
1781 if (NULL == pLinkLayerStatsClearReq)
1782 {
1783 hddLog(VOS_TRACE_LEVEL_ERROR,
1784 FL("Unable to allocate memory to pLinkLayerStatsClearReq"));
1785 return -ENOMEM;
1786 }
1787
1788 statsClearReqMask = pLinkLayerStatsClearReq->statsClearReqMask =
1789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
1792 stopReq = pLinkLayerStatsClearReq->stopReq =
1793 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.
1797 pLinkLayerStatsClearReq->reqId = 1;
1798
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 */
1803 pLinkLayerStatsClearReq->staId = pAdapter->sessionId + 1;
1804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
1806 "LL_STATS_CLEAR reqId = %d", pLinkLayerStatsClearReq->reqId);
1807 hddLog(VOS_TRACE_LEVEL_INFO,
1808 "LL_STATS_CLEAR staId = %d", pLinkLayerStatsClearReq->staId);
1809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
1811 pLinkLayerStatsClearReq->statsClearReqMask);
1812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
1814 pLinkLayerStatsClearReq->stopReq);
1815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
1817 pLinkLayerStatsClearReq))
1818 {
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 ,
1842 * the request to get the statistics are ehonoured as in this
1843 * case the firmware is just asked to clear the statistics.
1844 */
1845 if (pLinkLayerStatsClearReq->stopReq == 1)
1846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
1851 vos_mem_free(pLinkLayerStatsClearReq);
1852 return -EINVAL;
1853}
1854#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1855
Dino Mycle6fb96c12014-06-10 11:52:40 +05301856#ifdef WLAN_FEATURE_EXTSCAN
1857static const struct nla_policy
1858wlan_hdd_extscan_config_policy
1859 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1860{
1861 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1862 { .type = NLA_U32 },
1863 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1864 { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1866 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1867 { .type = NLA_U32 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1869 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1870
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1875 { .type = NLA_U8 },
1876 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1877 { .type = NLA_U32 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1879 { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1881 { .type = NLA_U32 },
1882 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1883 { .type = NLA_U8 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1885 { .type = NLA_U8 },
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1887 { .type = NLA_U8 },
1888
1889 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1890 { .type = NLA_U32 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1892 { .type = NLA_UNSPEC },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1894 { .type = NLA_S32 },
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1896 { .type = NLA_S32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1898 { .type = NLA_U32 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1900 { .type = NLA_U32 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1902 { .type = NLA_U32 },
1903 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1904 = { .type = NLA_U32 },
1905 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1906 { .type = NLA_U32 },
1907 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1908 NLA_U32 },
1909};
1910
1911static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1912{
1913 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1914 struct sk_buff *skb = NULL;
1915 tpSirEXTScanCapabilitiesEvent pData =
1916 (tpSirEXTScanCapabilitiesEvent) pMsg;
1917
1918 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1920 "or pData(%p) is null"), pData);
1921 return;
1922 }
1923
1924 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1925 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1926 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1927 GFP_KERNEL);
1928
1929 if (!skb) {
1930 hddLog(VOS_TRACE_LEVEL_ERROR,
1931 FL("cfg80211_vendor_event_alloc failed"));
1932 return;
1933 }
1934
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1939 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1940 pData->maxRssiSampleSize);
1941 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1942 pData->maxScanReportingThreshold);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1944 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1945 pData->maxSignificantWifiChangeAPs);
1946 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1947 pData->maxBsidHistoryEntries);
1948
1949 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1950 pData->requestId) ||
1951 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1952 nla_put_u32(skb,
1953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1954 pData->scanCacheSize) ||
1955 nla_put_u32(skb,
1956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1957 pData->scanBuckets) ||
1958 nla_put_u32(skb,
1959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1960 pData->maxApPerScan) ||
1961 nla_put_u32(skb,
1962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1963 pData->maxRssiSampleSize) ||
1964 nla_put_u32(skb,
1965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1966 pData->maxScanReportingThreshold) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1969 pData->maxHotlistAPs) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1972 pData->maxSignificantWifiChangeAPs) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1975 pData->maxBsidHistoryEntries)) {
1976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1977 goto nla_put_failure;
1978 }
1979
1980 cfg80211_vendor_event(skb, GFP_KERNEL);
1981 return;
1982
1983nla_put_failure:
1984 kfree_skb(skb);
1985 return;
1986}
1987
1988
1989static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1990{
1991 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1992 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1993 struct sk_buff *skb = NULL;
1994 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1995
1996
1997 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1999 "or pData(%p) is null"), pData);
2000 return;
2001 }
2002
2003 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2004 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2005 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2006 GFP_KERNEL);
2007
2008 if (!skb) {
2009 hddLog(VOS_TRACE_LEVEL_ERROR,
2010 FL("cfg80211_vendor_event_alloc failed"));
2011 return;
2012 }
2013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2015 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2016
2017 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2018 pData->requestId) ||
2019 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2021 goto nla_put_failure;
2022 }
2023
2024 /*
2025 * Store the Request ID for comparing with the requestID obtained
2026 * in other requests.HDD shall return a failure is the extscan_stop
2027 * request is issued with a different requestId as that of the
2028 * extscan_start request. Also, This requestId shall be used while
2029 * indicating the full scan results to the upper layers.
2030 * The requestId is stored with the assumption that the firmware
2031 * shall return the ext scan start request's requestId in ext scan
2032 * start response.
2033 */
2034 if (pData->status == 0)
2035 pMac->sme.extScanStartReqId = pData->requestId;
2036
2037
2038 cfg80211_vendor_event(skb, GFP_KERNEL);
2039 return;
2040
2041nla_put_failure:
2042 kfree_skb(skb);
2043 return;
2044}
2045
2046
2047static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2048{
2049 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2050 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2051 struct sk_buff *skb = NULL;
2052
2053 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2055 "or pData(%p) is null"), pData);
2056 return;
2057 }
2058
2059 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2060 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2061 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2062 GFP_KERNEL);
2063
2064 if (!skb) {
2065 hddLog(VOS_TRACE_LEVEL_ERROR,
2066 FL("cfg80211_vendor_event_alloc failed"));
2067 return;
2068 }
2069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2070 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2071
2072 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2073 pData->requestId) ||
2074 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2076 goto nla_put_failure;
2077 }
2078
2079 cfg80211_vendor_event(skb, GFP_KERNEL);
2080 return;
2081
2082nla_put_failure:
2083 kfree_skb(skb);
2084 return;
2085}
2086
2087
2088static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2089 void *pMsg)
2090{
2091 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2092 struct sk_buff *skb = NULL;
2093 tpSirEXTScanSetBssidHotListRspParams pData =
2094 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2095
2096 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2098 "or pData(%p) is null"), pData);
2099 return;
2100 }
2101 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2102 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2103 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2104 GFP_KERNEL);
2105
2106 if (!skb) {
2107 hddLog(VOS_TRACE_LEVEL_ERROR,
2108 FL("cfg80211_vendor_event_alloc failed"));
2109 return;
2110 }
2111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2113 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2114
2115 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2116 pData->requestId) ||
2117 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2119 goto nla_put_failure;
2120 }
2121
2122 cfg80211_vendor_event(skb, GFP_KERNEL);
2123 return;
2124
2125nla_put_failure:
2126 kfree_skb(skb);
2127 return;
2128}
2129
2130static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2131 void *pMsg)
2132{
2133 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2134 struct sk_buff *skb = NULL;
2135 tpSirEXTScanResetBssidHotlistRspParams pData =
2136 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2137
2138 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2140 "or pData(%p) is null"), pData);
2141 return;
2142 }
2143
2144 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2145 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2146 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2147 GFP_KERNEL);
2148
2149 if (!skb) {
2150 hddLog(VOS_TRACE_LEVEL_ERROR,
2151 FL("cfg80211_vendor_event_alloc failed"));
2152 return;
2153 }
2154 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2155 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2156
2157 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2158 pData->requestId) ||
2159 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2161 goto nla_put_failure;
2162 }
2163
2164 cfg80211_vendor_event(skb, GFP_KERNEL);
2165 return;
2166
2167nla_put_failure:
2168 kfree_skb(skb);
2169 return;
2170}
2171
2172
2173static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2174 void *pMsg)
2175{
2176 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2177 struct sk_buff *skb = NULL;
2178 tpSirEXTScanSetSignificantChangeRspParams pData =
2179 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2180
2181 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2183 "or pData(%p) is null"), pData);
2184 return;
2185 }
2186
2187 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2188 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2189 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2190 GFP_KERNEL);
2191
2192 if (!skb) {
2193 hddLog(VOS_TRACE_LEVEL_ERROR,
2194 FL("cfg80211_vendor_event_alloc failed"));
2195 return;
2196 }
2197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2199 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2200
2201 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2202 pData->requestId) ||
2203 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2205 goto nla_put_failure;
2206 }
2207
2208 cfg80211_vendor_event(skb, GFP_KERNEL);
2209 return;
2210
2211nla_put_failure:
2212 kfree_skb(skb);
2213 return;
2214}
2215
2216
2217static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2218 void *pMsg)
2219{
2220 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2221 struct sk_buff *skb = NULL;
2222 tpSirEXTScanResetSignificantChangeRspParams pData =
2223 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2224
2225 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2227 "or pData(%p) is null"), pData);
2228 return;
2229 }
2230
2231 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2232 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2233 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2234 GFP_KERNEL);
2235
2236 if (!skb) {
2237 hddLog(VOS_TRACE_LEVEL_ERROR,
2238 FL("cfg80211_vendor_event_alloc failed"));
2239 return;
2240 }
2241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2243 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2244
2245 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2246 pData->requestId) ||
2247 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2249 goto nla_put_failure;
2250 }
2251
2252 cfg80211_vendor_event(skb, GFP_KERNEL);
2253 return;
2254
2255nla_put_failure:
2256 kfree_skb(skb);
2257 return;
2258}
2259
2260static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2261 void *pMsg)
2262{
2263 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2264 struct sk_buff *skb = NULL;
2265 tANI_U32 i = 0, j, resultsPerEvent;
2266 tANI_S32 totalResults;
2267 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2268 tpSirWifiScanResult pSirWifiScanResult;
2269
2270 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2272 "or pData(%p) is null"), pData);
2273 return;
2274 }
2275 totalResults = pData->numOfAps;
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2278 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2279
2280 do{
2281 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2282 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2283 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2284
2285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2286 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2287 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2288 GFP_KERNEL);
2289
2290 if (!skb) {
2291 hddLog(VOS_TRACE_LEVEL_ERROR,
2292 FL("cfg80211_vendor_event_alloc failed"));
2293 return;
2294 }
2295
2296 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2297
2298 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2299 pData->requestId) ||
2300 nla_put_u32(skb,
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2302 resultsPerEvent)) {
2303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2304 goto fail;
2305 }
2306 if (nla_put_u8(skb,
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2308 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2309 {
2310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2311 goto fail;
2312 }
2313
2314 if (resultsPerEvent) {
2315 struct nlattr *aps;
2316
2317 aps = nla_nest_start(skb,
2318 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2319 if (!aps)
2320 {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2322 goto fail;
2323 }
2324
2325 for (j = 0; j < resultsPerEvent; j++, i++) {
2326 struct nlattr *ap;
2327 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2328 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2329
2330 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2331 "Ssid (%s)"
2332 "Bssid: %pM "
2333 "Channel (%u)"
2334 "Rssi (%d)"
2335 "RTT (%u)"
2336 "RTT_SD (%u)",
2337 i,
2338 pSirWifiScanResult->ts,
2339 pSirWifiScanResult->ssid,
2340 pSirWifiScanResult->bssid,
2341 pSirWifiScanResult->channel,
2342 pSirWifiScanResult->rssi,
2343 pSirWifiScanResult->rtt,
2344 pSirWifiScanResult->rtt_sd);
2345
2346 ap = nla_nest_start(skb, j + 1);
2347 if (!ap)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2350 goto fail;
2351 }
2352
2353 if (nla_put_u64(skb,
2354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2355 pSirWifiScanResult->ts) )
2356 {
2357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2358 goto fail;
2359 }
2360 if (nla_put(skb,
2361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2362 sizeof(pSirWifiScanResult->ssid),
2363 pSirWifiScanResult->ssid) )
2364 {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2366 goto fail;
2367 }
2368 if (nla_put(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2370 sizeof(pSirWifiScanResult->bssid),
2371 pSirWifiScanResult->bssid) )
2372 {
2373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2374 goto fail;
2375 }
2376 if (nla_put_u32(skb,
2377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2378 pSirWifiScanResult->channel) )
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2381 goto fail;
2382 }
2383 if (nla_put_u32(skb,
2384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2385 pSirWifiScanResult->rssi) )
2386 {
2387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2388 goto fail;
2389 }
2390 if (nla_put_u32(skb,
2391 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2392 pSirWifiScanResult->rtt) )
2393 {
2394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2395 goto fail;
2396 }
2397 if (nla_put_u32(skb,
2398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2399 pSirWifiScanResult->rtt_sd))
2400 {
2401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2402 goto fail;
2403 }
2404
2405 nla_nest_end(skb, ap);
2406 }
2407 nla_nest_end(skb, aps);
2408
2409 }
2410 cfg80211_vendor_event(skb, GFP_KERNEL);
2411 } while (totalResults > 0);
2412
2413 return;
2414fail:
2415 kfree_skb(skb);
2416 return;
2417}
2418
2419static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2420 void *pMsg)
2421{
2422 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tANI_U32 i;
2426
2427 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2429 "or pData(%p) is null"), pData);
2430 return;
2431 }
2432
2433 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2434 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2435 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2436 GFP_KERNEL);
2437
2438 if (!skb) {
2439 hddLog(VOS_TRACE_LEVEL_ERROR,
2440 FL("cfg80211_vendor_event_alloc failed"));
2441 return;
2442 }
2443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2446 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2447
2448 for (i = 0; i < pData->numOfAps; i++) {
2449 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2450 "Ssid (%s) "
2451 "Bssid (" MAC_ADDRESS_STR ") "
2452 "Channel (%u) "
2453 "Rssi (%d) "
2454 "RTT (%u) "
2455 "RTT_SD (%u) ",
2456 i,
2457 pData->ap[i].ts,
2458 pData->ap[i].ssid,
2459 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2460 pData->ap[i].channel,
2461 pData->ap[i].rssi,
2462 pData->ap[i].rtt,
2463 pData->ap[i].rtt_sd);
2464 }
2465
2466 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2467 pData->requestId) ||
2468 nla_put_u32(skb,
2469 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2470 pData->numOfAps)) {
2471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2472 goto fail;
2473 }
2474 if (pData->numOfAps) {
2475 struct nlattr *aps;
2476
2477 aps = nla_nest_start(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2479 if (!aps)
2480 goto fail;
2481
2482 for (i = 0; i < pData->numOfAps; i++) {
2483 struct nlattr *ap;
2484
2485 ap = nla_nest_start(skb, i + 1);
2486 if (!ap)
2487 goto fail;
2488
2489 if (nla_put_u64(skb,
2490 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2491 pData->ap[i].ts) ||
2492 nla_put(skb,
2493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2494 sizeof(pData->ap[i].ssid),
2495 pData->ap[i].ssid) ||
2496 nla_put(skb,
2497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2498 sizeof(pData->ap[i].bssid),
2499 pData->ap[i].bssid) ||
2500 nla_put_u32(skb,
2501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2502 pData->ap[i].channel) ||
2503 nla_put_s32(skb,
2504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2505 pData->ap[i].rssi) ||
2506 nla_put_u32(skb,
2507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2508 pData->ap[i].rtt) ||
2509 nla_put_u32(skb,
2510 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2511 pData->ap[i].rtt_sd))
2512 goto fail;
2513
2514 nla_nest_end(skb, ap);
2515 }
2516 nla_nest_end(skb, aps);
2517
2518 if (nla_put_u8(skb,
2519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2520 pData->moreData))
2521 goto fail;
2522 }
2523
2524 cfg80211_vendor_event(skb, GFP_KERNEL);
2525 return;
2526
2527fail:
2528 kfree_skb(skb);
2529 return;
2530
2531}
2532static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2533 void *pMsg)
2534{
2535 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2536 struct sk_buff *skb = NULL;
2537 tANI_U32 i, j;
2538 tpSirWifiSignificantChangeEvent pData =
2539 (tpSirWifiSignificantChangeEvent) pMsg;
2540
2541 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2543 "or pData(%p) is null"), pData);
2544 return;
2545 }
2546 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2547 EXTSCAN_EVENT_BUF_SIZE,
2548 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2549 GFP_KERNEL);
2550
2551 if (!skb) {
2552 hddLog(VOS_TRACE_LEVEL_ERROR,
2553 FL("cfg80211_vendor_event_alloc failed"));
2554 return;
2555 }
2556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2557 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2558 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2559 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2560 pData->numSigRssiBss);
2561 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2562
2563 for (i = 0; i < pData->numSigRssiBss; i++) {
2564 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2565 " num RSSI %u ",
2566 i, pData->sigRssiResult[i].bssid,
2567 pData->sigRssiResult[i].channel,
2568 pData->sigRssiResult[i].numRssi);
2569
2570 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2571
2572 hddLog(VOS_TRACE_LEVEL_INFO,
2573 " [%d]",
2574 pData->sigRssiResult[i].rssi[0]);
2575
2576 }
2577 }
2578
2579
2580 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2581 pData->requestId) ||
2582 nla_put_u32(skb,
2583 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2584 pData->numSigRssiBss)) {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2586 goto fail;
2587 }
2588
2589 if (pData->numSigRssiBss) {
2590 struct nlattr *aps;
2591 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2592 if (!aps)
2593 goto fail;
2594 for (i = 0; i < pData->numSigRssiBss; i++) {
2595 struct nlattr *ap;
2596
2597 ap = nla_nest_start(skb, i);
2598 if (!ap)
2599 goto fail;
2600 if (nla_put(skb,
2601 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2602 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2603 nla_put_u32(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2605 pData->sigRssiResult[i].channel) ||
2606 nla_put_u32(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2608 pData->sigRssiResult[i].numRssi) ||
2609 nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2611 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2612 pData->sigRssiResult[i].rssi))
2613 goto fail;
2614 nla_nest_end(skb, ap);
2615 }
2616 nla_nest_end(skb, aps);
2617 if (nla_put_u8(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2619 pData->moreData))
2620 goto fail;
2621 }
2622 cfg80211_vendor_event(skb, GFP_KERNEL);
2623 return;
2624fail:
2625 kfree_skb(skb);
2626 return;
2627}
2628
2629static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2630 void *pMsg)
2631{
2632 struct sk_buff *skb;
2633 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2634 tpSirWifiFullScanResultEvent pData =
2635 (tpSirWifiFullScanResultEvent) (pMsg);
2636
2637 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2639 "or pData(%p) is null"), pData);
2640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2644 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2645 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2646 GFP_KERNEL);
2647
2648 if (!skb) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR,
2650 FL("cfg80211_vendor_event_alloc failed"));
2651 return;
2652 }
2653
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2657 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2658 "Ssid (%s)"
2659 "Bssid (" MAC_ADDRESS_STR ")"
2660 "Channel (%u)"
2661 "Rssi (%d)"
2662 "RTT (%u)"
2663 "RTT_SD (%u)"),
2664 pData->ap.ts,
2665 pData->ap.ssid,
2666 MAC_ADDR_ARRAY(pData->ap.bssid),
2667 pData->ap.channel,
2668 pData->ap.rssi,
2669 pData->ap.rtt,
2670 pData->ap.rtt_sd);
2671 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u64(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2676 pData->ap.ts) ||
2677 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2678 sizeof(pData->ap.ssid),
2679 pData->ap.ssid) ||
2680 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2681 WNI_CFG_BSSID_LEN,
2682 pData->ap.bssid) ||
2683 nla_put_u32(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2685 pData->ap.channel) ||
2686 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2687 pData->ap.rssi) ||
2688 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2689 pData->ap.rtt) ||
2690 nla_put_u32(skb,
2691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2692 pData->ap.rtt_sd) ||
2693 nla_put_u16(skb,
2694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2695 pData->ap.beaconPeriod) ||
2696 nla_put_u16(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2698 pData->ap.capability) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2701 pData->ieLength))
2702 {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2704 goto nla_put_failure;
2705 }
2706 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2707 pData->ieLength,
2708 pData->ie))
2709 {
2710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2711 goto nla_put_failure;
2712 }
2713
2714 cfg80211_vendor_event(skb, GFP_KERNEL);
2715 return;
2716
2717nla_put_failure:
2718 kfree_skb(skb);
2719 return;
2720}
2721
2722static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2723 void *pMsg)
2724{
2725 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2726 struct sk_buff *skb = NULL;
2727 tpSirEXTScanResultsAvailableIndParams pData =
2728 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2729
2730 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2732 "or pData(%p) is null"), pData);
2733 return;
2734 }
2735
2736 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2737 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2738 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2739 GFP_KERNEL);
2740
2741 if (!skb) {
2742 hddLog(VOS_TRACE_LEVEL_ERROR,
2743 FL("cfg80211_vendor_event_alloc failed"));
2744 return;
2745 }
2746
2747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2749 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2750 pData->numResultsAvailable);
2751 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2752 pData->requestId) ||
2753 nla_put_u32(skb,
2754 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2755 pData->numResultsAvailable)) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2757 goto nla_put_failure;
2758 }
2759
2760 cfg80211_vendor_event(skb, GFP_KERNEL);
2761 return;
2762
2763nla_put_failure:
2764 kfree_skb(skb);
2765 return;
2766}
2767
2768static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2769{
2770 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2771 struct sk_buff *skb = NULL;
2772 tpSirEXTScanProgressIndParams pData =
2773 (tpSirEXTScanProgressIndParams) pMsg;
2774
2775 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2777 "or pData(%p) is null"), pData);
2778 return;
2779 }
2780
2781 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2782 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2783 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2784 GFP_KERNEL);
2785
2786 if (!skb) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR,
2788 FL("cfg80211_vendor_event_alloc failed"));
2789 return;
2790 }
2791 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2792 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2793 pData->extScanEventType);
2794 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2795 pData->status);
2796
2797 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2798 pData->extScanEventType) ||
2799 nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2801 pData->status)) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2803 goto nla_put_failure;
2804 }
2805
2806 cfg80211_vendor_event(skb, GFP_KERNEL);
2807 return;
2808
2809nla_put_failure:
2810 kfree_skb(skb);
2811 return;
2812}
2813
2814void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2815 void *pMsg)
2816{
2817 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2818
2819 if (wlan_hdd_validate_context(pHddCtx)) {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2821 return;
2822 }
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2825
2826
2827 switch(evType) {
2828 case SIR_HAL_EXTSCAN_START_RSP:
2829 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2830 break;
2831
2832 case SIR_HAL_EXTSCAN_STOP_RSP:
2833 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2834 break;
2835 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2836 /* There is no need to send this response to upper layer
2837 Just log the message */
2838 hddLog(VOS_TRACE_LEVEL_INFO,
2839 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2840 break;
2841 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2842 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2843 break;
2844
2845 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2846 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2847 break;
2848
2849 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2850 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2851 break;
2852
2853 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2854 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2855 break;
2856 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2857 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2858 break;
2859 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2860 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2861 break;
2862 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2863 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2864 break;
2865 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2866 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2867 break;
2868 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2869 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2870 break;
2871 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2872 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2875 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2876 break;
2877 default:
2878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2879 break;
2880 }
2881}
2882
2883static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2884 struct wireless_dev *wdev,
2885 void *data, int dataLen)
2886{
2887 tpSirGetEXTScanCapabilitiesReqParams pReqMsg = NULL;
2888 struct net_device *dev = wdev->netdev;
2889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2890 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2891 struct nlattr
2892 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2893 eHalStatus status;
2894
2895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2896 status = wlan_hdd_validate_context(pHddCtx);
2897 if (0 != status)
2898 {
2899 hddLog(VOS_TRACE_LEVEL_ERROR,
2900 FL("HDD context is not valid"));
2901 return -EINVAL;
2902 }
2903 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2904 data, dataLen,
2905 wlan_hdd_extscan_config_policy)) {
2906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2907 return -EINVAL;
2908 }
2909
2910 /* Parse and fetch request Id */
2911 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2913 return -EINVAL;
2914 }
2915
2916 pReqMsg = (tpSirGetEXTScanCapabilitiesReqParams)
2917 vos_mem_malloc(sizeof(*pReqMsg));
2918 if (!pReqMsg) {
2919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2920 return -ENOMEM;
2921 }
2922
2923 pReqMsg->requestId = nla_get_u32(
2924 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2925 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2926
2927 pReqMsg->sessionId = pAdapter->sessionId;
2928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2929
2930 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, pReqMsg);
2931 if (!HAL_STATUS_SUCCESS(status)) {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
2934 vos_mem_free(pReqMsg);
2935 return -EINVAL;
2936 }
2937
2938 return 0;
2939}
2940
2941
2942static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2943 struct wireless_dev *wdev,
2944 void *data, int dataLen)
2945{
2946 tpSirEXTScanGetCachedResultsReqParams pReqMsg = NULL;
2947 struct net_device *dev = wdev->netdev;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2950 struct nlattr
2951 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2952 eHalStatus status;
2953
2954 status = wlan_hdd_validate_context(pHddCtx);
2955 if (0 != status)
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR,
2958 FL("HDD context is not valid"));
2959 return -EINVAL;
2960 }
2961 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2962 data, dataLen,
2963 wlan_hdd_extscan_config_policy)) {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2965 return -EINVAL;
2966 }
2967 /* Parse and fetch request Id */
2968 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2970 return -EINVAL;
2971 }
2972 pReqMsg = (tpSirEXTScanGetCachedResultsReqParams)
2973 vos_mem_malloc(sizeof(*pReqMsg));
2974 if (!pReqMsg) {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2976 return -ENOMEM;
2977 }
2978
2979 pReqMsg->requestId = nla_get_u32(
2980 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2981
2982 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2983
2984 pReqMsg->sessionId = pAdapter->sessionId;
2985 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2986
2987 /* Parse and fetch flush parameter */
2988 if (!tb
2989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2990 {
2991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2992 goto failed;
2993 }
2994 pReqMsg->flush = nla_get_u8(
2995 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
2996
2997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush);
2998
2999 status = sme_getCachedResults(pHddCtx->hHal, pReqMsg);
3000 if (!HAL_STATUS_SUCCESS(status)) {
3001 hddLog(VOS_TRACE_LEVEL_ERROR,
3002 FL("sme_getCachedResults failed(err=%d)"), status);
3003 vos_mem_free(pReqMsg);
3004 return -EINVAL;
3005 }
3006 return 0;
3007
3008failed:
3009 vos_mem_free(pReqMsg);
3010 return -EINVAL;
3011}
3012
3013static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3014 struct wireless_dev *wdev,
3015 void *data, int dataLen)
3016{
3017 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3018 struct net_device *dev = wdev->netdev;
3019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3020 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3021 struct nlattr
3022 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3023 struct nlattr
3024 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3025 struct nlattr *apTh;
3026 eHalStatus status;
3027 tANI_U8 i = 0;
3028 int rem;
3029
3030 status = wlan_hdd_validate_context(pHddCtx);
3031 if (0 != status)
3032 {
3033 hddLog(VOS_TRACE_LEVEL_ERROR,
3034 FL("HDD context is not valid"));
3035 return -EINVAL;
3036 }
3037 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3038 data, dataLen,
3039 wlan_hdd_extscan_config_policy)) {
3040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3041 return -EINVAL;
3042 }
3043
3044 /* Parse and fetch request Id */
3045 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3047 return -EINVAL;
3048 }
3049
3050 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3051 vos_mem_malloc(sizeof(*pReqMsg));
3052 if (!pReqMsg) {
3053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3054 return -ENOMEM;
3055 }
3056
3057 pReqMsg->requestId = nla_get_u32(
3058 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3060
3061 /* Parse and fetch number of APs */
3062 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3064 goto fail;
3065 }
3066
3067 pReqMsg->sessionId = pAdapter->sessionId;
3068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3069
3070 pReqMsg->numAp = nla_get_u32(
3071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3072 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3073
3074 nla_for_each_nested(apTh,
3075 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3076 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3077 nla_data(apTh), nla_len(apTh),
3078 NULL)) {
3079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3080 goto fail;
3081 }
3082
3083 /* Parse and fetch MAC address */
3084 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3086 goto fail;
3087 }
3088 memcpy(pReqMsg->ap[i].bssid, nla_data(
3089 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3090 sizeof(tSirMacAddr));
3091 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3092
3093 /* Parse and fetch low RSSI */
3094 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3096 goto fail;
3097 }
3098 pReqMsg->ap[i].low = nla_get_s32(
3099 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3101
3102 /* Parse and fetch high RSSI */
3103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3105 goto fail;
3106 }
3107 pReqMsg->ap[i].high = nla_get_s32(
3108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3109 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3110 pReqMsg->ap[i].high);
3111
3112 /* Parse and fetch channel */
3113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3115 goto fail;
3116 }
3117 pReqMsg->ap[i].channel = nla_get_u32(
3118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3119 hddLog(VOS_TRACE_LEVEL_INFO,
3120 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3121 i++;
3122 }
3123 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3124 if (!HAL_STATUS_SUCCESS(status)) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR,
3126 FL("sme_SetBssHotlist failed(err=%d)"), status);
3127 vos_mem_free(pReqMsg);
3128 return -EINVAL;
3129 }
3130
3131 return 0;
3132
3133fail:
3134 vos_mem_free(pReqMsg);
3135 return -EINVAL;
3136}
3137
3138static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3139 struct wireless_dev *wdev,
3140 void *data, int dataLen)
3141{
3142 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3143 struct net_device *dev = wdev->netdev;
3144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3145 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3146 struct nlattr
3147 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3148 struct nlattr
3149 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3150 struct nlattr *apTh;
3151 eHalStatus status;
3152 int i = 0;
3153 int rem;
3154
3155 status = wlan_hdd_validate_context(pHddCtx);
3156 if (0 != status)
3157 {
3158 hddLog(VOS_TRACE_LEVEL_ERROR,
3159 FL("HDD context is not valid"));
3160 return -EINVAL;
3161 }
3162 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3163 data, dataLen,
3164 wlan_hdd_extscan_config_policy)) {
3165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3166 return -EINVAL;
3167 }
3168
3169 /* Parse and fetch request Id */
3170 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3172 return -EINVAL;
3173 }
3174
3175 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
3176 vos_mem_malloc(sizeof(*pReqMsg));
3177 if (!pReqMsg) {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3179 return -ENOMEM;
3180 }
3181
3182 pReqMsg->requestId = nla_get_u32(
3183 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3185
3186 /* Parse and fetch RSSI sample size */
3187 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3188 {
3189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3190 goto fail;
3191 }
3192 pReqMsg->rssiSampleSize = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3194 hddLog(VOS_TRACE_LEVEL_INFO,
3195 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3196
3197 /* Parse and fetch lost AP sample size */
3198 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3201 goto fail;
3202 }
3203 pReqMsg->lostApSampleSize = nla_get_u32(
3204 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3205 hddLog(VOS_TRACE_LEVEL_INFO,
3206 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3207 /* Parse and fetch minimum Breaching */
3208 if (!tb
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3211 goto fail;
3212 }
3213 pReqMsg->minBreaching = nla_get_u32(
3214 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3215 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3216
3217 /* Parse and fetch number of APs */
3218 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3220 goto fail;
3221 }
3222 pReqMsg->numAp = nla_get_u32(
3223 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3225
3226 pReqMsg->sessionId = pAdapter->sessionId;
3227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3228
3229 nla_for_each_nested(apTh,
3230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3231 if(nla_parse(tb2,
3232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3233 nla_data(apTh), nla_len(apTh),
3234 NULL)) {
3235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3236 goto fail;
3237 }
3238
3239 /* Parse and fetch MAC address */
3240 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3242 goto fail;
3243 }
3244 memcpy(pReqMsg->ap[i].bssid, nla_data(
3245 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3246 sizeof(tSirMacAddr));
3247
3248 /* Parse and fetch low RSSI */
3249 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3251 goto fail;
3252 }
3253 pReqMsg->ap[i].low = nla_get_s32(
3254 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3255 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3256
3257 /* Parse and fetch high RSSI */
3258 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3260 goto fail;
3261 }
3262 pReqMsg->ap[i].high = nla_get_s32(
3263 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3264 hddLog(VOS_TRACE_LEVEL_INFO,
3265 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3266
3267 /* Parse and fetch channel */
3268 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3270 goto fail;
3271 }
3272 pReqMsg->ap[i].channel = nla_get_u32(
3273 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3274 hddLog(VOS_TRACE_LEVEL_INFO,
3275 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3276 i++;
3277 }
3278
3279 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3280 if (!HAL_STATUS_SUCCESS(status)) {
3281 hddLog(VOS_TRACE_LEVEL_ERROR,
3282 FL("sme_SetSignificantChange failed(err=%d)"), status);
3283 vos_mem_free(pReqMsg);
3284 return -EINVAL;
3285 }
3286
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3288 return 0;
3289
3290fail:
3291 vos_mem_free(pReqMsg);
3292 return -EINVAL;
3293}
3294
3295static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3296 struct wireless_dev *wdev,
3297 void *data, int dataLen)
3298{
3299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3300 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3301 tANI_U8 numChannels = 0;
3302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3303 tANI_U32 requestId;
3304 tWifiBand wifiBand;
3305 eHalStatus status;
3306 struct sk_buff *replySkb;
3307 tANI_U8 i;
3308
3309 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3310 status = wlan_hdd_validate_context(pHddCtx);
3311 if (0 != status)
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR,
3314 FL("HDD context is not valid"));
3315 return -EINVAL;
3316 }
3317 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3318 data, dataLen,
3319 wlan_hdd_extscan_config_policy)) {
3320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3321 return -EINVAL;
3322 }
3323
3324 /* Parse and fetch request Id */
3325 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3327 return -EINVAL;
3328 }
3329 requestId = nla_get_u32(
3330 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3332
3333 /* Parse and fetch wifi band */
3334 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3335 {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3337 return -EINVAL;
3338 }
3339 wifiBand = nla_get_u32(
3340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3342
3343 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3344 wifiBand, ChannelList,
3345 &numChannels);
3346 if (eHAL_STATUS_SUCCESS != status) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3349 return -EINVAL;
3350 }
3351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3352 for (i = 0; i < numChannels; i++)
3353 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3354
3355 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3356 sizeof(u32) * numChannels +
3357 NLMSG_HDRLEN);
3358
3359 if (!replySkb) {
3360 hddLog(VOS_TRACE_LEVEL_ERROR,
3361 FL("valid channels: buffer alloc fail"));
3362 return -EINVAL;
3363 }
3364 if (nla_put_u32(replySkb,
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3366 numChannels) ||
3367 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3368 sizeof(u32) * numChannels, ChannelList)) {
3369
3370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3371 kfree_skb(replySkb);
3372 return -EINVAL;
3373 }
3374
3375 return cfg80211_vendor_cmd_reply(replySkb);
3376}
3377
3378static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3379 struct wireless_dev *wdev,
3380 void *data, int dataLen)
3381{
3382 tpSirEXTScanStartReqParams pReqMsg = NULL;
3383 struct net_device *dev = wdev->netdev;
3384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3386 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3387 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3388 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr *buckets;
3390 struct nlattr *channels;
3391 int rem1;
3392 int rem2;
3393 eHalStatus status;
3394 tANI_U8 bktIndex;
3395 tANI_U32 i = 0, j = 0;
3396
3397 status = wlan_hdd_validate_context(pHddCtx);
3398 if (0 != status)
3399 {
3400 hddLog(VOS_TRACE_LEVEL_ERROR,
3401 FL("HDD context is not valid"));
3402 return -EINVAL;
3403 }
3404 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3405 data, dataLen,
3406 wlan_hdd_extscan_config_policy)) {
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3408 return -EINVAL;
3409 }
3410
3411 /* Parse and fetch request Id */
3412 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3414 return -EINVAL;
3415 }
3416
3417 pReqMsg = (tpSirEXTScanStartReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3418 if (!pReqMsg) {
3419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3420 return -ENOMEM;
3421 }
3422
3423 pReqMsg->requestId = nla_get_u32(
3424 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3425 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3426
3427 pReqMsg->sessionId = pAdapter->sessionId;
3428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3429
3430 /* Parse and fetch base period */
3431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3433 goto fail;
3434 }
3435 pReqMsg->basePeriod = nla_get_u32(
3436 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3437 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3438 pReqMsg->basePeriod);
3439
3440 /* Parse and fetch max AP per scan */
3441 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3443 goto fail;
3444 }
3445 pReqMsg->maxAPperScan = nla_get_u32(
3446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3448 pReqMsg->maxAPperScan);
3449
3450 /* Parse and fetch report threshold */
3451 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3453 goto fail;
3454 }
3455 pReqMsg->reportThreshold = nla_get_u8(
3456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3458 pReqMsg->reportThreshold);
3459
3460 /* Parse and fetch number of buckets */
3461 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3463 goto fail;
3464 }
3465 pReqMsg->numBuckets = nla_get_u8(
3466 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3467 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3468 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3469 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3470 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3471 }
3472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3473 pReqMsg->numBuckets);
3474 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3476 goto fail;
3477 }
3478
3479 nla_for_each_nested(buckets,
3480 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3481 if(nla_parse(bucket,
3482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3483 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3485 goto fail;
3486 }
3487
3488 /* Parse and fetch bucket spec */
3489 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3491 goto fail;
3492 }
3493 bktIndex = nla_get_u8(
3494 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3496 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3497
3498 /* Parse and fetch wifi band */
3499 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3501 goto fail;
3502 }
3503 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3504 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3506 pReqMsg->buckets[bktIndex].band);
3507
3508 /* Parse and fetch period */
3509 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3511 goto fail;
3512 }
3513 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3514 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3515 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3516 pReqMsg->buckets[bktIndex].period);
3517
3518 /* Parse and fetch report events */
3519 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3521 goto fail;
3522 }
3523 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3524 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3525 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3526 pReqMsg->buckets[bktIndex].reportEvents);
3527
3528 /* Parse and fetch number of channels */
3529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3531 goto fail;
3532 }
3533 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3534 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3535 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3536 pReqMsg->buckets[bktIndex].numChannels);
3537
3538 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3540 goto fail;
3541 }
3542
3543 j = 0;
3544 nla_for_each_nested(channels,
3545 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3546 if(nla_parse(channel,
3547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3548 nla_data(channels), nla_len(channels),
3549 NULL)) { //wlan_hdd_extscan_config_policy here
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3551 goto fail;
3552 }
3553
3554 /* Parse and fetch channel */
3555 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3557 goto fail;
3558 }
3559 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3560 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3561 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3562 pReqMsg->buckets[bktIndex].channels[j].channel);
3563
3564 /* Parse and fetch dwell time */
3565 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3567 goto fail;
3568 }
3569 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3570 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3572 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3573
3574 /* Parse and fetch channel spec passive */
3575 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3576 hddLog(VOS_TRACE_LEVEL_ERROR,
3577 FL("attr channel spec passive failed"));
3578 goto fail;
3579 }
3580 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3581 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3582 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3583 pReqMsg->buckets[bktIndex].channels[j].passive);
3584 j++;
3585 }
3586 i++;
3587 }
3588 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3589 if (!HAL_STATUS_SUCCESS(status)) {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("sme_EXTScanStart failed(err=%d)"), status);
3592 vos_mem_free(pReqMsg);
3593 return -EINVAL;
3594 }
3595
3596 return 0;
3597
3598fail:
3599 vos_mem_free(pReqMsg);
3600 return -EINVAL;
3601}
3602
3603static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3604 struct wireless_dev *wdev,
3605 void *data, int dataLen)
3606{
3607 tpSirEXTScanStopReqParams pReqMsg = NULL;
3608 struct net_device *dev = wdev->netdev;
3609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3611 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3612 eHalStatus status;
3613
3614 status = wlan_hdd_validate_context(pHddCtx);
3615 if (0 != status)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR,
3618 FL("HDD context is not valid"));
3619 return -EINVAL;
3620 }
3621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3622 data, dataLen,
3623 wlan_hdd_extscan_config_policy)) {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3625 return -EINVAL;
3626 }
3627
3628 /* Parse and fetch request Id */
3629 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3631 return -EINVAL;
3632 }
3633
3634 pReqMsg = (tpSirEXTScanStopReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3635 if (!pReqMsg) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3637 return -ENOMEM;
3638 }
3639
3640 pReqMsg->requestId = nla_get_u32(
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3643
3644 pReqMsg->sessionId = pAdapter->sessionId;
3645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3646
3647 status = sme_EXTScanStop(pHddCtx->hHal, pReqMsg);
3648 if (!HAL_STATUS_SUCCESS(status)) {
3649 hddLog(VOS_TRACE_LEVEL_ERROR,
3650 FL("sme_EXTScanStop failed(err=%d)"), status);
3651 vos_mem_free(pReqMsg);
3652 return -EINVAL;
3653 }
3654
3655 return 0;
3656}
3657
3658static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3659 struct wireless_dev *wdev,
3660 void *data, int dataLen)
3661{
3662 tpSirEXTScanResetBssidHotlistReqParams pReqMsg = NULL;
3663 struct net_device *dev = wdev->netdev;
3664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3665 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3666 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3667 eHalStatus status;
3668
3669 status = wlan_hdd_validate_context(pHddCtx);
3670 if (0 != status)
3671 {
3672 hddLog(VOS_TRACE_LEVEL_ERROR,
3673 FL("HDD context is not valid"));
3674 return -EINVAL;
3675 }
3676 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
3689 pReqMsg = (tpSirEXTScanResetBssidHotlistReqParams)
3690 vos_mem_malloc(sizeof(*pReqMsg));
3691 if (!pReqMsg) {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3693 return -ENOMEM;
3694 }
3695
3696 pReqMsg->requestId = nla_get_u32(
3697 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3699
3700 pReqMsg->sessionId = pAdapter->sessionId;
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3702
3703 status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
3704 if (!HAL_STATUS_SUCCESS(status)) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR,
3706 FL("sme_ResetBssHotlist failed(err=%d)"), status);
3707 vos_mem_free(pReqMsg);
3708 return -EINVAL;
3709 }
3710
3711 return 0;
3712}
3713
3714static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3715 struct wiphy *wiphy,
3716 struct wireless_dev *wdev,
3717 void *data, int dataLen)
3718{
3719 tpSirEXTScanResetSignificantChangeReqParams pReqMsg = NULL;
3720 struct net_device *dev = wdev->netdev;
3721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3722 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3723 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3724 eHalStatus status;
3725
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3727 status = wlan_hdd_validate_context(pHddCtx);
3728 if (0 != status)
3729 {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 FL("HDD context is not valid"));
3732 return -EINVAL;
3733 }
3734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3735 data, dataLen,
3736 wlan_hdd_extscan_config_policy)) {
3737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3738 return -EINVAL;
3739 }
3740
3741 /* Parse and fetch request Id */
3742 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3744 return -EINVAL;
3745 }
3746
3747 pReqMsg = (tpSirEXTScanResetSignificantChangeReqParams)
3748 vos_mem_malloc(sizeof(*pReqMsg));
3749 if (!pReqMsg) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3751 return -ENOMEM;
3752 }
3753
3754 pReqMsg->requestId = nla_get_u32(
3755 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3757
3758 pReqMsg->sessionId = pAdapter->sessionId;
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3760
3761 status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
3762 if (!HAL_STATUS_SUCCESS(status)) {
3763 hddLog(VOS_TRACE_LEVEL_ERROR,
3764 FL("sme_ResetSignificantChange failed(err=%d)"), status);
3765 vos_mem_free(pReqMsg);
3766 return -EINVAL;
3767 }
3768
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3770 return 0;
3771}
3772
3773#endif /* WLAN_FEATURE_EXTSCAN */
3774
Sunil Duttc69bccb2014-05-26 21:30:20 +05303775const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3776{
3777#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3778 {
3779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3782 WIPHY_VENDOR_CMD_NEED_NETDEV |
3783 WIPHY_VENDOR_CMD_NEED_RUNNING,
3784 .doit = wlan_hdd_cfg80211_ll_stats_clear
3785 },
3786
3787 {
3788 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3789 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3790 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3791 WIPHY_VENDOR_CMD_NEED_NETDEV |
3792 WIPHY_VENDOR_CMD_NEED_RUNNING,
3793 .doit = wlan_hdd_cfg80211_ll_stats_set
3794 },
3795
3796 {
3797 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3798 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3799 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3800 WIPHY_VENDOR_CMD_NEED_NETDEV |
3801 WIPHY_VENDOR_CMD_NEED_RUNNING,
3802 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303804#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805#ifdef WLAN_FEATURE_EXTSCAN
3806 {
3807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3810 WIPHY_VENDOR_CMD_NEED_NETDEV |
3811 WIPHY_VENDOR_CMD_NEED_RUNNING,
3812 .doit = wlan_hdd_cfg80211_extscan_start
3813 },
3814 {
3815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3818 WIPHY_VENDOR_CMD_NEED_NETDEV |
3819 WIPHY_VENDOR_CMD_NEED_RUNNING,
3820 .doit = wlan_hdd_cfg80211_extscan_stop
3821 },
3822 {
3823 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3824 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3826 WIPHY_VENDOR_CMD_NEED_NETDEV,
3827 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3828 },
3829 {
3830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3833 WIPHY_VENDOR_CMD_NEED_NETDEV |
3834 WIPHY_VENDOR_CMD_NEED_RUNNING,
3835 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3836 },
3837 {
3838 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3839 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3840 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3841 WIPHY_VENDOR_CMD_NEED_NETDEV |
3842 WIPHY_VENDOR_CMD_NEED_RUNNING,
3843 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3844 },
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3852 },
3853 {
3854 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3855 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3856 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3857 WIPHY_VENDOR_CMD_NEED_NETDEV |
3858 WIPHY_VENDOR_CMD_NEED_RUNNING,
3859 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3860 },
3861 {
3862 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3863 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3864 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3865 WIPHY_VENDOR_CMD_NEED_NETDEV |
3866 WIPHY_VENDOR_CMD_NEED_RUNNING,
3867 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3868 },
3869 {
3870 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3871 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3872 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3873 WIPHY_VENDOR_CMD_NEED_NETDEV |
3874 WIPHY_VENDOR_CMD_NEED_RUNNING,
3875 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3876 },
3877#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303878};
3879
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003880/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303881static const
3882struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003883{
3884#ifdef FEATURE_WLAN_CH_AVOID
3885 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303886 .vendor_id = QCA_NL80211_VENDOR_ID,
3887 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003888 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303889#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3890#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3891 {
3892 /* Index = 1*/
3893 .vendor_id = QCA_NL80211_VENDOR_ID,
3894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3895 },
3896 {
3897 /* Index = 2*/
3898 .vendor_id = QCA_NL80211_VENDOR_ID,
3899 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3900 },
3901 {
3902 /* Index = 3*/
3903 .vendor_id = QCA_NL80211_VENDOR_ID,
3904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3905 },
3906 {
3907 /* Index = 4*/
3908 .vendor_id = QCA_NL80211_VENDOR_ID,
3909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3910 },
3911 {
3912 /* Index = 5*/
3913 .vendor_id = QCA_NL80211_VENDOR_ID,
3914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3915 },
3916 {
3917 /* Index = 6*/
3918 .vendor_id = QCA_NL80211_VENDOR_ID,
3919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3920 },
3921#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922#ifdef WLAN_FEATURE_EXTSCAN
3923 {
3924 .vendor_id = QCA_NL80211_VENDOR_ID,
3925 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3926 },
3927 {
3928 .vendor_id = QCA_NL80211_VENDOR_ID,
3929 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3930 },
3931 {
3932 .vendor_id = QCA_NL80211_VENDOR_ID,
3933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3934 },
3935 {
3936 .vendor_id = QCA_NL80211_VENDOR_ID,
3937 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3938 },
3939 {
3940 .vendor_id = QCA_NL80211_VENDOR_ID,
3941 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3942 },
3943 {
3944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3946 },
3947 {
3948 .vendor_id = QCA_NL80211_VENDOR_ID,
3949 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
3950 },
3951 {
3952 .vendor_id = QCA_NL80211_VENDOR_ID,
3953 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
3954 },
3955 {
3956 .vendor_id = QCA_NL80211_VENDOR_ID,
3957 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
3958 },
3959 {
3960 .vendor_id = QCA_NL80211_VENDOR_ID,
3961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
3962 },
3963 {
3964 .vendor_id = QCA_NL80211_VENDOR_ID,
3965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
3966 },
3967 {
3968 .vendor_id = QCA_NL80211_VENDOR_ID,
3969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
3970 },
3971 {
3972 .vendor_id = QCA_NL80211_VENDOR_ID,
3973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
3974 },
3975#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303976
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003977};
3978
Jeff Johnson295189b2012-06-20 16:38:30 -07003979/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303980 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303981 * This function is called by hdd_wlan_startup()
3982 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303983 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303985struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07003986{
3987 struct wiphy *wiphy;
3988 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303989 /*
3990 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 */
3992 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
3993
3994 if (!wiphy)
3995 {
3996 /* Print error and jump into err label and free the memory */
3997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
3998 return NULL;
3999 }
4000
Sunil Duttc69bccb2014-05-26 21:30:20 +05304001
Jeff Johnson295189b2012-06-20 16:38:30 -07004002 return wiphy;
4003}
4004
4005/*
4006 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 * private ioctl to change the band value
4009 */
4010int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4011{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304012 int i, j;
4013 eNVChannelEnabledType channelEnabledState;
4014
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304016
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304017 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304019
4020 if (NULL == wiphy->bands[i])
4021 {
4022 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4023 __func__, i);
4024 continue;
4025 }
4026
4027 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4028 {
4029 struct ieee80211_supported_band *band = wiphy->bands[i];
4030
4031 channelEnabledState = vos_nv_getChannelEnabledState(
4032 band->channels[j].hw_value);
4033
4034 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4035 {
4036 // Enable Social channels for P2P
4037 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4038 NV_CHANNEL_ENABLE == channelEnabledState)
4039 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4040 else
4041 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4042 continue;
4043 }
4044 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4045 {
4046 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4047 continue;
4048 }
4049
4050 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4051 NV_CHANNEL_INVALID == channelEnabledState)
4052 {
4053 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4054 }
4055 else if (NV_CHANNEL_DFS == channelEnabledState)
4056 {
4057 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4058 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4059 }
4060 else
4061 {
4062 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4063 |IEEE80211_CHAN_RADAR);
4064 }
4065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 }
4067 return 0;
4068}
4069/*
4070 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 * This function is called by hdd_wlan_startup()
4072 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 * This function is used to initialize and register wiphy structure.
4074 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304075int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 struct wiphy *wiphy,
4077 hdd_config_t *pCfg
4078 )
4079{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304080 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304081 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4082
Jeff Johnsone7245742012-09-05 17:12:55 -07004083 ENTER();
4084
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 /* Now bind the underlying wlan device with wiphy */
4086 set_wiphy_dev(wiphy, dev);
4087
4088 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004089
Kiet Lam6c583332013-10-14 05:37:09 +05304090#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004091 /* the flag for the other case would be initialzed in
4092 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004093 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304094#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004095
Amar Singhalfddc28c2013-09-05 13:03:40 -07004096 /* This will disable updating of NL channels from passive to
4097 * active if a beacon is received on passive channel. */
4098 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004099
Amar Singhalfddc28c2013-09-05 13:03:40 -07004100
Amar Singhala49cbc52013-10-08 18:37:44 -07004101
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004103 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4104 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4105 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004106 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304107 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004109
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004111 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004112#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004113 || pCfg->isFastRoamIniFeatureEnabled
4114#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004115#ifdef FEATURE_WLAN_ESE
4116 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004117#endif
4118 )
4119 {
4120 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4121 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004122#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004123#ifdef FEATURE_WLAN_TDLS
4124 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4125 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4126#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304127#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304128 if (pCfg->configPNOScanSupport)
4129 {
4130 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4131 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4132 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4133 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4134 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304135#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004136
Amar Singhalfddc28c2013-09-05 13:03:40 -07004137#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004138 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4139 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004141 driver need to determine what to do with both
4142 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004143
4144 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004145#else
4146 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004148
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4150
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304151 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004152
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304153 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4154
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4159 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 | BIT(NL80211_IFTYPE_AP);
4161
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304162 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004163 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4165 if( pCfg->enableMCC )
4166 {
4167 /* Currently, supports up to two channels */
4168 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004169
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304170 if( !pCfg->allowMCCGODiffBI )
4171 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004172
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304173 }
4174 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4175 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004176#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304177 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004178
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 /* Before registering we need to update the ht capabilitied based
4180 * on ini values*/
4181 if( !pCfg->ShortGI20MhzEnable )
4182 {
4183 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4184 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4185 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4186 }
4187
4188 if( !pCfg->ShortGI40MhzEnable )
4189 {
4190 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4191 }
4192
4193 if( !pCfg->nChannelBondingMode5GHz )
4194 {
4195 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4196 }
4197
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304198 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304199 if (true == hdd_is_5g_supported(pHddCtx))
4200 {
4201 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4202 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304203
4204 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4205 {
4206
4207 if (NULL == wiphy->bands[i])
4208 {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4210 __func__, i);
4211 continue;
4212 }
4213
4214 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4215 {
4216 struct ieee80211_supported_band *band = wiphy->bands[i];
4217
4218 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4219 {
4220 // Enable social channels for P2P
4221 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4222 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4223 else
4224 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4225 continue;
4226 }
4227 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4228 {
4229 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4230 continue;
4231 }
4232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 }
4234 /*Initialise the supported cipher suite details*/
4235 wiphy->cipher_suites = hdd_cipher_suites;
4236 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4237
4238 /*signal strength in mBm (100*dBm) */
4239 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4240
4241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 wiphy->max_remain_on_channel_duration = 1000;
4243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
Sunil Duttc69bccb2014-05-26 21:30:20 +05304245 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4246 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004247 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4248 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4249
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304250 EXIT();
4251 return 0;
4252}
4253
4254/* In this function we are registering wiphy. */
4255int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4256{
4257 ENTER();
4258 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 if (0 > wiphy_register(wiphy))
4260 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304261 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4263 return -EIO;
4264 }
4265
4266 EXIT();
4267 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268}
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304270/* In this function we are updating channel list when,
4271 regulatory domain is FCC and country code is US.
4272 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4273 As per FCC smart phone is not a indoor device.
4274 GO should not opeate on indoor channels */
4275void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4276{
4277 int j;
4278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4279 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4280 //Default counrtycode from NV at the time of wiphy initialization.
4281 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4282 &defaultCountryCode[0]))
4283 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004284 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304285 }
4286 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4287 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304288 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4291 return;
4292 }
4293 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4294 {
4295 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4296 // Mark UNII -1 band channel as passive
4297 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4298 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4299 }
4300 }
4301}
4302
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304303/* This function registers for all frame which supplicant is interested in */
4304void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004305{
Jeff Johnson295189b2012-06-20 16:38:30 -07004306 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4307 /* Register for all P2P action, public action etc frames */
4308 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4309
Jeff Johnsone7245742012-09-05 17:12:55 -07004310 ENTER();
4311
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 /* Right now we are registering these frame when driver is getting
4313 initialized. Once we will move to 2.6.37 kernel, in which we have
4314 frame register ops, we will move this code as a part of that */
4315 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4318
4319 /* GAS Initial Response */
4320 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4321 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304322
Jeff Johnson295189b2012-06-20 16:38:30 -07004323 /* GAS Comeback Request */
4324 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4325 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4326
4327 /* GAS Comeback Response */
4328 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4329 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4330
4331 /* P2P Public Action */
4332 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304333 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004334 P2P_PUBLIC_ACTION_FRAME_SIZE );
4335
4336 /* P2P Action */
4337 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4338 (v_U8_t*)P2P_ACTION_FRAME,
4339 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004340
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304341 /* WNM BSS Transition Request frame */
4342 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4343 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4344 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004345
4346 /* WNM-Notification */
4347 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4348 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4349 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004350}
4351
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304352void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004353{
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4355 /* Register for all P2P action, public action etc frames */
4356 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4357
Jeff Johnsone7245742012-09-05 17:12:55 -07004358 ENTER();
4359
Jeff Johnson295189b2012-06-20 16:38:30 -07004360 /* Right now we are registering these frame when driver is getting
4361 initialized. Once we will move to 2.6.37 kernel, in which we have
4362 frame register ops, we will move this code as a part of that */
4363 /* GAS Initial Request */
4364
4365 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4366 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4367
4368 /* GAS Initial Response */
4369 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4370 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304371
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 /* GAS Comeback Request */
4373 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4374 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4375
4376 /* GAS Comeback Response */
4377 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4378 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4379
4380 /* P2P Public Action */
4381 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304382 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 P2P_PUBLIC_ACTION_FRAME_SIZE );
4384
4385 /* P2P Action */
4386 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4387 (v_U8_t*)P2P_ACTION_FRAME,
4388 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004389 /* WNM-Notification */
4390 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4391 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4392 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004393}
4394
4395#ifdef FEATURE_WLAN_WAPI
4396void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4397 const u8 *mac_addr, u8 *key , int key_Len)
4398{
4399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4400 tCsrRoamSetKey setKey;
4401 v_BOOL_t isConnected = TRUE;
4402 int status = 0;
4403 v_U32_t roamId= 0xFF;
4404 tANI_U8 *pKeyPtr = NULL;
4405 int n = 0;
4406
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304407 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4408 __func__, hdd_device_modetoString(pAdapter->device_mode),
4409 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004410
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304411 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 setKey.keyId = key_index; // Store Key ID
4413 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4414 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4415 setKey.paeRole = 0 ; // the PAE role
4416 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4417 {
4418 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4419 }
4420 else
4421 {
4422 isConnected = hdd_connIsConnected(pHddStaCtx);
4423 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4424 }
4425 setKey.keyLength = key_Len;
4426 pKeyPtr = setKey.Key;
4427 memcpy( pKeyPtr, key, key_Len);
4428
Arif Hussain6d2a3322013-11-17 19:50:10 -08004429 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 __func__, key_Len);
4431 for (n = 0 ; n < key_Len; n++)
4432 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4433 __func__,n,setKey.Key[n]);
4434
4435 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4436 if ( isConnected )
4437 {
4438 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4439 pAdapter->sessionId, &setKey, &roamId );
4440 }
4441 if ( status != 0 )
4442 {
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4444 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4445 __LINE__, status );
4446 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4447 }
4448}
4449#endif /* FEATURE_WLAN_WAPI*/
4450
4451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304452int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 beacon_data_t **ppBeacon,
4454 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004455#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304456int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004457 beacon_data_t **ppBeacon,
4458 struct cfg80211_beacon_data *params,
4459 int dtim_period)
4460#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304461{
Jeff Johnson295189b2012-06-20 16:38:30 -07004462 int size;
4463 beacon_data_t *beacon = NULL;
4464 beacon_data_t *old = NULL;
4465 int head_len,tail_len;
4466
Jeff Johnsone7245742012-09-05 17:12:55 -07004467 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304469 {
4470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4471 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004472 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004474
4475 old = pAdapter->sessionCtx.ap.beacon;
4476
4477 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304478 {
4479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4480 FL("session(%d) old and new heads points to NULL"),
4481 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004482 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304483 }
4484
4485 if (params->tail && !params->tail_len)
4486 {
4487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4488 FL("tail_len is zero but tail is not NULL"));
4489 return -EINVAL;
4490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004491
Jeff Johnson295189b2012-06-20 16:38:30 -07004492#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4493 /* Kernel 3.0 is not updating dtim_period for set beacon */
4494 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304495 {
4496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4497 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004498 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004500#endif
4501
4502 if(params->head)
4503 head_len = params->head_len;
4504 else
4505 head_len = old->head_len;
4506
4507 if(params->tail || !old)
4508 tail_len = params->tail_len;
4509 else
4510 tail_len = old->tail_len;
4511
4512 size = sizeof(beacon_data_t) + head_len + tail_len;
4513
4514 beacon = kzalloc(size, GFP_KERNEL);
4515
4516 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304517 {
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4519 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004522
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004523#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 if(params->dtim_period || !old )
4525 beacon->dtim_period = params->dtim_period;
4526 else
4527 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004528#else
4529 if(dtim_period || !old )
4530 beacon->dtim_period = dtim_period;
4531 else
4532 beacon->dtim_period = old->dtim_period;
4533#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304534
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4536 beacon->tail = beacon->head + head_len;
4537 beacon->head_len = head_len;
4538 beacon->tail_len = tail_len;
4539
4540 if(params->head) {
4541 memcpy (beacon->head,params->head,beacon->head_len);
4542 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304543 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 if(old)
4545 memcpy (beacon->head,old->head,beacon->head_len);
4546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304547
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 if(params->tail) {
4549 memcpy (beacon->tail,params->tail,beacon->tail_len);
4550 }
4551 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304552 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 memcpy (beacon->tail,old->tail,beacon->tail_len);
4554 }
4555
4556 *ppBeacon = beacon;
4557
4558 kfree(old);
4559
4560 return 0;
4561
4562}
Jeff Johnson295189b2012-06-20 16:38:30 -07004563
4564v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4565{
4566 int left = length;
4567 v_U8_t *ptr = pIes;
4568 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304569
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 elem_id = ptr[0];
4573 elem_len = ptr[1];
4574 left -= 2;
4575 if(elem_len > left)
4576 {
4577 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004578 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004579 eid,elem_len,left);
4580 return NULL;
4581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304582 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 {
4584 return ptr;
4585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304586
Jeff Johnson295189b2012-06-20 16:38:30 -07004587 left -= elem_len;
4588 ptr += (elem_len + 2);
4589 }
4590 return NULL;
4591}
4592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593/* Check if rate is 11g rate or not */
4594static int wlan_hdd_rate_is_11g(u8 rate)
4595{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004596 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 u8 i;
4598 for (i = 0; i < 8; i++)
4599 {
4600 if(rate == gRateArray[i])
4601 return TRUE;
4602 }
4603 return FALSE;
4604}
4605
4606/* Check for 11g rate and set proper 11g only mode */
4607static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4608 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4609{
4610 u8 i, num_rates = pIe[0];
4611
4612 pIe += 1;
4613 for ( i = 0; i < num_rates; i++)
4614 {
4615 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4616 {
4617 /* If rate set have 11g rate than change the mode to 11G */
4618 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4619 if (pIe[i] & BASIC_RATE_MASK)
4620 {
4621 /* If we have 11g rate as basic rate, it means mode
4622 is 11g only mode.
4623 */
4624 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4625 *pCheckRatesfor11g = FALSE;
4626 }
4627 }
4628 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4629 {
4630 *require_ht = TRUE;
4631 }
4632 }
4633 return;
4634}
4635
4636static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4637{
4638 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4639 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4640 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4641 u8 checkRatesfor11g = TRUE;
4642 u8 require_ht = FALSE;
4643 u8 *pIe=NULL;
4644
4645 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4646
4647 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4648 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4649 if (pIe != NULL)
4650 {
4651 pIe += 1;
4652 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4653 &pConfig->SapHw_mode);
4654 }
4655
4656 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4657 WLAN_EID_EXT_SUPP_RATES);
4658 if (pIe != NULL)
4659 {
4660
4661 pIe += 1;
4662 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4663 &pConfig->SapHw_mode);
4664 }
4665
4666 if( pConfig->channel > 14 )
4667 {
4668 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4669 }
4670
4671 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4672 WLAN_EID_HT_CAPABILITY);
4673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304674 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 {
4676 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4677 if(require_ht)
4678 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4679 }
4680}
4681
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304682static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4683 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4684{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004685 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304686 v_U8_t *pIe = NULL;
4687 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4688
4689 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4690 pBeacon->tail, pBeacon->tail_len);
4691
4692 if (pIe)
4693 {
4694 ielen = pIe[1] + 2;
4695 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4696 {
4697 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4698 }
4699 else
4700 {
4701 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4702 return -EINVAL;
4703 }
4704 *total_ielen += ielen;
4705 }
4706 return 0;
4707}
4708
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004709static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4710 v_U8_t *genie, v_U8_t *total_ielen)
4711{
4712 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4713 int left = pBeacon->tail_len;
4714 v_U8_t *ptr = pBeacon->tail;
4715 v_U8_t elem_id, elem_len;
4716 v_U16_t ielen = 0;
4717
4718 if ( NULL == ptr || 0 == left )
4719 return;
4720
4721 while (left >= 2)
4722 {
4723 elem_id = ptr[0];
4724 elem_len = ptr[1];
4725 left -= 2;
4726 if (elem_len > left)
4727 {
4728 hddLog( VOS_TRACE_LEVEL_ERROR,
4729 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4730 elem_id, elem_len, left);
4731 return;
4732 }
4733 if (IE_EID_VENDOR == elem_id)
4734 {
4735 /* skipping the VSIE's which we don't want to include or
4736 * it will be included by existing code
4737 */
4738 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4739#ifdef WLAN_FEATURE_WFD
4740 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4741#endif
4742 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4743 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4744 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4745 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4746 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4747 {
4748 ielen = ptr[1] + 2;
4749 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4750 {
4751 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4752 *total_ielen += ielen;
4753 }
4754 else
4755 {
4756 hddLog( VOS_TRACE_LEVEL_ERROR,
4757 "IE Length is too big "
4758 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4759 elem_id, elem_len, *total_ielen);
4760 }
4761 }
4762 }
4763
4764 left -= elem_len;
4765 ptr += (elem_len + 2);
4766 }
4767 return;
4768}
4769
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004770#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004771static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4772 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004773#else
4774static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4775 struct cfg80211_beacon_data *params)
4776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004777{
4778 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304779 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004781 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004782
4783 genie = vos_mem_malloc(MAX_GENIE_LEN);
4784
4785 if(genie == NULL) {
4786
4787 return -ENOMEM;
4788 }
4789
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304790 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4791 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304793 hddLog(LOGE,
4794 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304795 ret = -EINVAL;
4796 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004797 }
4798
4799#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304800 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4801 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4802 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304803 hddLog(LOGE,
4804 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304805 ret = -EINVAL;
4806 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 }
4808#endif
4809
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304810 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4811 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004812 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304813 hddLog(LOGE,
4814 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304815 ret = -EINVAL;
4816 goto done;
4817 }
4818
Abhishek Singh5128c4f2014-06-04 14:48:31 +05304819 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4820 &total_ielen, WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE))
4821 {
4822 hddLog(LOGE, FL("Adding WMM IE failed"));
4823 ret = -EINVAL;
4824 goto done;
4825 }
4826
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304827 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4828 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004829 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004831
4832 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4833 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4834 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4835 {
4836 hddLog(LOGE,
4837 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004838 ret = -EINVAL;
4839 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 }
4841
4842 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4843 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4844 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4845 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4846 ==eHAL_STATUS_FAILURE)
4847 {
4848 hddLog(LOGE,
4849 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004850 ret = -EINVAL;
4851 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 }
4853
4854 // Added for ProResp IE
4855 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4856 {
4857 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4858 u8 probe_rsp_ie_len[3] = {0};
4859 u8 counter = 0;
4860 /* Check Probe Resp Length if it is greater then 255 then Store
4861 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4862 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4863 Store More then 255 bytes into One Variable.
4864 */
4865 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4866 {
4867 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4868 {
4869 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4870 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4871 }
4872 else
4873 {
4874 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4875 rem_probe_resp_ie_len = 0;
4876 }
4877 }
4878
4879 rem_probe_resp_ie_len = 0;
4880
4881 if (probe_rsp_ie_len[0] > 0)
4882 {
4883 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4884 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4885 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4886 probe_rsp_ie_len[0], NULL,
4887 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4888 {
4889 hddLog(LOGE,
4890 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004891 ret = -EINVAL;
4892 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 }
4894 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4895 }
4896
4897 if (probe_rsp_ie_len[1] > 0)
4898 {
4899 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4900 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4901 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4902 probe_rsp_ie_len[1], NULL,
4903 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4904 {
4905 hddLog(LOGE,
4906 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004907 ret = -EINVAL;
4908 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004909 }
4910 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4911 }
4912
4913 if (probe_rsp_ie_len[2] > 0)
4914 {
4915 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4916 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4917 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4918 probe_rsp_ie_len[2], NULL,
4919 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4920 {
4921 hddLog(LOGE,
4922 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004923 ret = -EINVAL;
4924 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 }
4926 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4927 }
4928
4929 if (probe_rsp_ie_len[1] == 0 )
4930 {
4931 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4932 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4933 eANI_BOOLEAN_FALSE) )
4934 {
4935 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004936 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004937 }
4938 }
4939
4940 if (probe_rsp_ie_len[2] == 0 )
4941 {
4942 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4944 eANI_BOOLEAN_FALSE) )
4945 {
4946 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004947 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 }
4949 }
4950
4951 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4952 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4953 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4954 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4955 == eHAL_STATUS_FAILURE)
4956 {
4957 hddLog(LOGE,
4958 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004959 ret = -EINVAL;
4960 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 }
4962 }
4963 else
4964 {
4965 // Reset WNI_CFG_PROBE_RSP Flags
4966 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
4967
4968 hddLog(VOS_TRACE_LEVEL_INFO,
4969 "%s: No Probe Response IE received in set beacon",
4970 __func__);
4971 }
4972
4973 // Added for AssocResp IE
4974 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
4975 {
4976 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4977 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
4978 params->assocresp_ies_len, NULL,
4979 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4980 {
4981 hddLog(LOGE,
4982 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004983 ret = -EINVAL;
4984 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 }
4986
4987 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4988 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
4989 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4990 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4991 == eHAL_STATUS_FAILURE)
4992 {
4993 hddLog(LOGE,
4994 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004995 ret = -EINVAL;
4996 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 }
4998 }
4999 else
5000 {
5001 hddLog(VOS_TRACE_LEVEL_INFO,
5002 "%s: No Assoc Response IE received in set beacon",
5003 __func__);
5004
5005 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5006 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5007 eANI_BOOLEAN_FALSE) )
5008 {
5009 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005010 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 }
5012 }
5013
Jeff Johnsone7245742012-09-05 17:12:55 -07005014done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305016 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005017}
Jeff Johnson295189b2012-06-20 16:38:30 -07005018
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305019/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 * FUNCTION: wlan_hdd_validate_operation_channel
5021 * called by wlan_hdd_cfg80211_start_bss() and
5022 * wlan_hdd_cfg80211_set_channel()
5023 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305024 * channel list.
5025 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005026VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005027{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305028
Jeff Johnson295189b2012-06-20 16:38:30 -07005029 v_U32_t num_ch = 0;
5030 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5031 u32 indx = 0;
5032 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305033 v_U8_t fValidChannel = FALSE, count = 0;
5034 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305035
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5037
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305038 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305040 /* Validate the channel */
5041 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305043 if ( channel == rfChannels[count].channelNum )
5044 {
5045 fValidChannel = TRUE;
5046 break;
5047 }
5048 }
5049 if (fValidChannel != TRUE)
5050 {
5051 hddLog(VOS_TRACE_LEVEL_ERROR,
5052 "%s: Invalid Channel [%d]", __func__, channel);
5053 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 }
5055 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305056 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305058 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5059 valid_ch, &num_ch))
5060 {
5061 hddLog(VOS_TRACE_LEVEL_ERROR,
5062 "%s: failed to get valid channel list", __func__);
5063 return VOS_STATUS_E_FAILURE;
5064 }
5065 for (indx = 0; indx < num_ch; indx++)
5066 {
5067 if (channel == valid_ch[indx])
5068 {
5069 break;
5070 }
5071 }
5072
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305073 if (indx >= num_ch)
5074 {
5075 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5076 {
5077 eCsrBand band;
5078 unsigned int freq;
5079
5080 sme_GetFreqBand(hHal, &band);
5081
5082 if (eCSR_BAND_5G == band)
5083 {
5084#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5085 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5086 {
5087 freq = ieee80211_channel_to_frequency(channel,
5088 IEEE80211_BAND_2GHZ);
5089 }
5090 else
5091 {
5092 freq = ieee80211_channel_to_frequency(channel,
5093 IEEE80211_BAND_5GHZ);
5094 }
5095#else
5096 freq = ieee80211_channel_to_frequency(channel);
5097#endif
5098 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5099 return VOS_STATUS_SUCCESS;
5100 }
5101 }
5102
5103 hddLog(VOS_TRACE_LEVEL_ERROR,
5104 "%s: Invalid Channel [%d]", __func__, channel);
5105 return VOS_STATUS_E_FAILURE;
5106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005107 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305108
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305110
Jeff Johnson295189b2012-06-20 16:38:30 -07005111}
5112
Viral Modi3a32cc52013-02-08 11:14:52 -08005113/**
5114 * FUNCTION: wlan_hdd_cfg80211_set_channel
5115 * This function is used to set the channel number
5116 */
5117static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5118 struct ieee80211_channel *chan,
5119 enum nl80211_channel_type channel_type
5120 )
5121{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305122 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005123 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005124 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005125 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305126 hdd_context_t *pHddCtx;
5127 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005128
5129 ENTER();
5130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305131
Viral Modi3a32cc52013-02-08 11:14:52 -08005132 if( NULL == dev )
5133 {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005135 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005136 return -ENODEV;
5137 }
5138 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +05305139 if (NULL == pAdapter)
5140 {
5141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5142 "%s: HDD adapter context is Null", __func__);
5143 return -ENODEV;
5144 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5146 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5147 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005148 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305149 "%s: device_mode = %s (%d) freq = %d", __func__,
5150 hdd_device_modetoString(pAdapter->device_mode),
5151 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305152
5153 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5154 status = wlan_hdd_validate_context(pHddCtx);
5155
5156 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005157 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5159 "%s: HDD context is not valid", __func__);
5160 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005161 }
5162
5163 /*
5164 * Do freq to chan conversion
5165 * TODO: for 11a
5166 */
5167
5168 channel = ieee80211_frequency_to_channel(freq);
5169
5170 /* Check freq range */
5171 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5172 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5173 {
5174 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005175 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005176 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5177 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5178 return -EINVAL;
5179 }
5180
5181 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5182
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305183 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5184 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005185 {
5186 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5187 {
5188 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005189 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005190 return -EINVAL;
5191 }
5192 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5193 "%s: set channel to [%d] for device mode =%d",
5194 __func__, channel,pAdapter->device_mode);
5195 }
5196 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005197 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005198 )
5199 {
5200 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5201 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5202 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5203
5204 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5205 {
5206 /* Link is up then return cant set channel*/
5207 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005208 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005209 return -EINVAL;
5210 }
5211
5212 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5213 pHddStaCtx->conn_info.operationChannel = channel;
5214 pRoamProfile->ChannelInfo.ChannelList =
5215 &pHddStaCtx->conn_info.operationChannel;
5216 }
5217 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005219 )
5220 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305221 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5222 {
5223 if(VOS_STATUS_SUCCESS !=
5224 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);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305228 return -EINVAL;
5229 }
5230 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5231 }
5232 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005233 {
5234 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5235
5236 /* If auto channel selection is configured as enable/ 1 then ignore
5237 channel set by supplicant
5238 */
5239 if ( cfg_param->apAutoChannelSelection )
5240 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305241 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5242 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005243 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305244 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5245 __func__, hdd_device_modetoString(pAdapter->device_mode),
5246 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005247 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305248 else
5249 {
5250 if(VOS_STATUS_SUCCESS !=
5251 wlan_hdd_validate_operation_channel(pAdapter,channel))
5252 {
5253 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005254 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305255 return -EINVAL;
5256 }
5257 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5258 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005259 }
5260 }
5261 else
5262 {
5263 hddLog(VOS_TRACE_LEVEL_FATAL,
5264 "%s: Invalid device mode failed to set valid channel", __func__);
5265 return -EINVAL;
5266 }
5267 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305268 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005269}
5270
Jeff Johnson295189b2012-06-20 16:38:30 -07005271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5272static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5273 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005274#else
5275static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5276 struct cfg80211_beacon_data *params,
5277 const u8 *ssid, size_t ssid_len,
5278 enum nl80211_hidden_ssid hidden_ssid)
5279#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005280{
5281 tsap_Config_t *pConfig;
5282 beacon_data_t *pBeacon = NULL;
5283 struct ieee80211_mgmt *pMgmt_frame;
5284 v_U8_t *pIe=NULL;
5285 v_U16_t capab_info;
5286 eCsrAuthType RSNAuthType;
5287 eCsrEncryptionType RSNEncryptType;
5288 eCsrEncryptionType mcRSNEncryptType;
5289 int status = VOS_STATUS_SUCCESS;
5290 tpWLAN_SAPEventCB pSapEventCallback;
5291 hdd_hostapd_state_t *pHostapdState;
5292 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5293 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305294 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005295 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305296 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005298 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005299 v_BOOL_t MFPCapable = VOS_FALSE;
5300 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305301 eHddDot11Mode sapDot11Mode =
5302 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005303
5304 ENTER();
5305
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305306 iniConfig = pHddCtx->cfg_ini;
5307
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5309
5310 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5311
5312 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5313
5314 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5315
5316 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5317
5318 //channel is already set in the set_channel Call back
5319 //pConfig->channel = pCommitConfig->channel;
5320
5321 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305322 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5324
5325 pConfig->dtim_period = pBeacon->dtim_period;
5326
Arif Hussain6d2a3322013-11-17 19:50:10 -08005327 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 pConfig->dtim_period);
5329
5330
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005331 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005332 {
5333 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305335 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5336 {
5337 tANI_BOOLEAN restartNeeded;
5338 pConfig->ieee80211d = 1;
5339 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5340 sme_setRegInfo(hHal, pConfig->countryCode);
5341 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5342 }
5343 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005345 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005346 pConfig->ieee80211d = 1;
5347 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5348 sme_setRegInfo(hHal, pConfig->countryCode);
5349 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005351 else
5352 {
5353 pConfig->ieee80211d = 0;
5354 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305355 /*
5356 * If auto channel is configured i.e. channel is 0,
5357 * so skip channel validation.
5358 */
5359 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5360 {
5361 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5362 {
5363 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005364 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305365 return -EINVAL;
5366 }
5367 }
5368 else
5369 {
5370 if(1 != pHddCtx->is_dynamic_channel_range_set)
5371 {
5372 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5373 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5374 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5375 }
5376 pHddCtx->is_dynamic_channel_range_set = 0;
5377 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005378 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005379 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 {
5381 pConfig->ieee80211d = 0;
5382 }
5383 pConfig->authType = eSAP_AUTO_SWITCH;
5384
5385 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305386
5387 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5389
5390 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5391
5392 /*Set wps station to configured*/
5393 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5394
5395 if(pIe)
5396 {
5397 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5398 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005399 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 return -EINVAL;
5401 }
5402 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5403 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005404 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 /* Check 15 bit of WPS IE as it contain information for wps state
5406 * WPS state
5407 */
5408 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5409 {
5410 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5411 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5412 {
5413 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5414 }
5415 }
5416 }
5417 else
5418 {
5419 pConfig->wps_state = SAP_WPS_DISABLED;
5420 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305421 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005422
c_hpothufe599e92014-06-16 11:38:55 +05305423 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5424 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5425 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5426 eCSR_ENCRYPT_TYPE_NONE;
5427
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 pConfig->RSNWPAReqIELength = 0;
5429 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 WLAN_EID_RSN);
5432 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305433 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5435 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5436 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305437 /* The actual processing may eventually be more extensive than
5438 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 * by the app.
5440 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305441 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5443 &RSNEncryptType,
5444 &mcRSNEncryptType,
5445 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005446 &MFPCapable,
5447 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 pConfig->pRSNWPAReqIE[1]+2,
5449 pConfig->pRSNWPAReqIE );
5450
5451 if( VOS_STATUS_SUCCESS == status )
5452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 /* Now copy over all the security attributes you have
5454 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 * */
5456 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5457 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5458 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5459 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305460 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005461 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5463 }
5464 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5467 pBeacon->tail, pBeacon->tail_len);
5468
5469 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5470 {
5471 if (pConfig->pRSNWPAReqIE)
5472 {
5473 /*Mixed mode WPA/WPA2*/
5474 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5475 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5476 }
5477 else
5478 {
5479 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5480 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5481 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5484 &RSNEncryptType,
5485 &mcRSNEncryptType,
5486 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005487 &MFPCapable,
5488 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 pConfig->pRSNWPAReqIE[1]+2,
5490 pConfig->pRSNWPAReqIE );
5491
5492 if( VOS_STATUS_SUCCESS == status )
5493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305494 /* Now copy over all the security attributes you have
5495 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 * */
5497 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5498 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5499 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5500 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305501 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005502 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5504 }
5505 }
5506 }
5507
Jeff Johnson4416a782013-03-25 14:17:50 -07005508 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5509 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5510 return -EINVAL;
5511 }
5512
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5514
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005515#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 if (params->ssid != NULL)
5517 {
5518 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5519 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5520 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5521 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5522 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005523#else
5524 if (ssid != NULL)
5525 {
5526 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5527 pConfig->SSIDinfo.ssid.length = ssid_len;
5528 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5529 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5530 }
5531#endif
5532
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305533 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305535
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 /* default value */
5537 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5538 pConfig->num_accept_mac = 0;
5539 pConfig->num_deny_mac = 0;
5540
5541 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5542 pBeacon->tail, pBeacon->tail_len);
5543
5544 /* pIe for black list is following form:
5545 type : 1 byte
5546 length : 1 byte
5547 OUI : 4 bytes
5548 acl type : 1 byte
5549 no of mac addr in black list: 1 byte
5550 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305551 */
5552 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 {
5554 pConfig->SapMacaddr_acl = pIe[6];
5555 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005556 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305558 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5559 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5561 for (i = 0; i < pConfig->num_deny_mac; i++)
5562 {
5563 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5564 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 }
5567 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5568 pBeacon->tail, pBeacon->tail_len);
5569
5570 /* pIe for white list is following form:
5571 type : 1 byte
5572 length : 1 byte
5573 OUI : 4 bytes
5574 acl type : 1 byte
5575 no of mac addr in white list: 1 byte
5576 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 */
5578 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 {
5580 pConfig->SapMacaddr_acl = pIe[6];
5581 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005582 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305584 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5585 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5587 for (i = 0; i < pConfig->num_accept_mac; i++)
5588 {
5589 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5590 acl_entry++;
5591 }
5592 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305593
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5595
Jeff Johnsone7245742012-09-05 17:12:55 -07005596#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005597 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305598 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5599 * 11ac in .ini and 11ac is supported by both host and firmware.
5600 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5601 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005602 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5603 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305604 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5605 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5606 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5607 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5608 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005609 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305610 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005611 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305612 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005613
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305614 /* If ACS disable and selected channel <= 14
5615 * OR
5616 * ACS enabled and ACS operating band is choosen as 2.4
5617 * AND
5618 * VHT in 2.4G Disabled
5619 * THEN
5620 * Fallback to 11N mode
5621 */
5622 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5623 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305624 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305625 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005626 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305627 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5628 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005629 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5630 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005631 }
5632#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305633
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005634 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5635 {
5636 sme_SelectCBMode(hHal,
5637 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5638 pConfig->channel);
5639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 // ht_capab is not what the name conveys,this is used for protection bitmap
5641 pConfig->ht_capab =
5642 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5643
5644 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5645 {
5646 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5647 return -EINVAL;
5648 }
5649
5650 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305651 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5653 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305654 pConfig->obssProtEnabled =
5655 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005656
Chet Lanctot8cecea22014-02-11 19:09:36 -08005657#ifdef WLAN_FEATURE_11W
5658 pConfig->mfpCapable = MFPCapable;
5659 pConfig->mfpRequired = MFPRequired;
5660 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5661 pConfig->mfpCapable, pConfig->mfpRequired);
5662#endif
5663
Arif Hussain6d2a3322013-11-17 19:50:10 -08005664 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005666 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5667 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5668 (int)pConfig->channel);
5669 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5670 pConfig->SapHw_mode, pConfig->privacy,
5671 pConfig->authType);
5672 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5673 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5674 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5675 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005676
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305677 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 {
5679 //Bss already started. just return.
5680 //TODO Probably it should update some beacon params.
5681 hddLog( LOGE, "Bss Already started...Ignore the request");
5682 EXIT();
5683 return 0;
5684 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 pConfig->persona = pHostapdAdapter->device_mode;
5687
5688 pSapEventCallback = hdd_hostapd_SAPEventCB;
5689 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5690 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5691 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005692 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 return -EINVAL;
5694 }
5695
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305696 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5698
5699 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305702 {
5703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005704 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005705 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 VOS_ASSERT(0);
5707 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5710
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005711#ifdef WLAN_FEATURE_P2P_DEBUG
5712 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5713 {
5714 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5715 {
5716 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5717 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005718 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005719 }
5720 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5721 {
5722 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5723 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005724 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005725 }
5726 }
5727#endif
5728
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 pHostapdState->bCommit = TRUE;
5730 EXIT();
5731
5732 return 0;
5733}
5734
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005735#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305736static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5737 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 struct beacon_parameters *params)
5739{
5740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05305741 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305742 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005743
5744 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05305745 if (NULL == pAdapter)
5746 {
5747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5748 "%s: HDD adapter context is Null", __func__);
5749 return -ENODEV;
5750 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305751 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5752 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5753 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305754 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5755 hdd_device_modetoString(pAdapter->device_mode),
5756 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005757
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305758 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5759 status = wlan_hdd_validate_context(pHddCtx);
5760
5761 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005762 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5764 "%s: HDD context is not valid", __func__);
5765 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005766 }
5767
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305768 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 )
5771 {
5772 beacon_data_t *old,*new;
5773
5774 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305775
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305777 {
5778 hddLog(VOS_TRACE_LEVEL_WARN,
5779 FL("already beacon info added to session(%d)"),
5780 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005781 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305782 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005783
5784 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 {
5788 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005789 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 return -EINVAL;
5791 }
5792
5793 pAdapter->sessionCtx.ap.beacon = new;
5794
5795 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5796 }
5797
5798 EXIT();
5799 return status;
5800}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801
5802static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 struct net_device *dev,
5804 struct beacon_parameters *params)
5805{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305806 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05305807 hdd_station_ctx_t *pHddStaCtx = NULL;
5808 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305809 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005810
5811 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05305812 if (NULL == pAdapter)
5813 {
5814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5815 "%s: HDD adapter context is Null", __func__);
5816 return -ENODEV;
5817 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sushant Kaushik10728722014-05-14 16:20:25 +05305819 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305820 status = wlan_hdd_validate_context(pHddCtx);
5821
5822 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005823 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5825 "%s: HDD context is not valid", __func__);
5826 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005827 }
Sushant Kaushik10728722014-05-14 16:20:25 +05305828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5829 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5830 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5832 __func__, hdd_device_modetoString(pAdapter->device_mode),
5833 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305836 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 {
5838 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305839
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305841
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305843 {
5844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5845 FL("session(%d) old and new heads points to NULL"),
5846 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005849
5850 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5851
5852 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305853 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005854 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 return -EINVAL;
5856 }
5857
5858 pAdapter->sessionCtx.ap.beacon = new;
5859
5860 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5861 }
5862
5863 EXIT();
5864 return status;
5865}
5866
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005867#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5868
5869#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005870static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5871 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005872#else
5873static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5874 struct net_device *dev)
5875#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005876{
5877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005878 hdd_context_t *pHddCtx = NULL;
5879 hdd_scaninfo_t *pScanInfo = NULL;
5880 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305881 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305882 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005883
5884 ENTER();
5885
5886 if (NULL == pAdapter)
5887 {
Sushant Kaushik10728722014-05-14 16:20:25 +05305888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005889 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 return -ENODEV;
5891 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005892
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305893 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5894 TRACE_CODE_HDD_CFG80211_STOP_AP,
5895 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305896 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5897 status = wlan_hdd_validate_context(pHddCtx);
5898
5899 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005900 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5902 "%s: HDD context is not valid", __func__);
5903 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005904 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005905
5906 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5907 if (NULL == staAdapter)
5908 {
5909 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5910 if (NULL == staAdapter)
5911 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5913 "%s: HDD adapter context for STA/P2P-CLI is Null",
5914 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005915 }
5916 }
5917
5918 pScanInfo = &pHddCtx->scan_info;
5919
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5921 __func__, hdd_device_modetoString(pAdapter->device_mode),
5922 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005923
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305924 ret = wlan_hdd_scan_abort(pAdapter);
5925
Girish Gowli4bf7a632014-06-12 13:42:11 +05305926 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005927 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5929 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305930
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305931 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005932 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5934 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005935
Jeff Johnsone7245742012-09-05 17:12:55 -07005936 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305937 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005938 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305939 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005940 }
5941
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305942 hdd_hostapd_stop(dev);
5943
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 )
5947 {
5948 beacon_data_t *old;
5949
5950 old = pAdapter->sessionCtx.ap.beacon;
5951
5952 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305953 {
5954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5955 FL("session(%d) beacon data points to NULL"),
5956 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005959
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962 mutex_lock(&pHddCtx->sap_lock);
5963 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5964 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005965 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 {
5967 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5968
5969 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5970
5971 if (!VOS_IS_STATUS_SUCCESS(status))
5972 {
5973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005974 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305976 }
5977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
5979 }
5980 mutex_unlock(&pHddCtx->sap_lock);
5981
5982 if(status != VOS_STATUS_SUCCESS)
5983 {
5984 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005985 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 return -EINVAL;
5987 }
5988
Jeff Johnson4416a782013-03-25 14:17:50 -07005989 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
5991 ==eHAL_STATUS_FAILURE)
5992 {
5993 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005994 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 }
5996
Jeff Johnson4416a782013-03-25 14:17:50 -07005997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5999 eANI_BOOLEAN_FALSE) )
6000 {
6001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 }
6004
6005 // Reset WNI_CFG_PROBE_RSP Flags
6006 wlan_hdd_reset_prob_rspies(pAdapter);
6007
6008 pAdapter->sessionCtx.ap.beacon = NULL;
6009 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006010#ifdef WLAN_FEATURE_P2P_DEBUG
6011 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6012 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6013 {
6014 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6015 "GO got removed");
6016 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6017 }
6018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 }
6020 EXIT();
6021 return status;
6022}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006023
6024#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6025
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306026static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6027 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006028 struct cfg80211_ap_settings *params)
6029{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306030 hdd_adapter_t *pAdapter;
6031 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306032 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006033
6034 ENTER();
6035
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306036 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306039 "%s: Device is Null", __func__);
6040 return -ENODEV;
6041 }
6042
6043 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6044 if (NULL == pAdapter)
6045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306047 "%s: HDD adapter is Null", __func__);
6048 return -ENODEV;
6049 }
6050
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306051 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6052 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6053 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306054 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306057 "%s: HDD adapter magic is invalid", __func__);
6058 return -ENODEV;
6059 }
6060
6061 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306062 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306063
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306064 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6067 "%s: HDD context is not valid", __func__);
6068 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306069 }
6070
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306071 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6072 __func__, hdd_device_modetoString(pAdapter->device_mode),
6073 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306074
6075 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006076 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006077 )
6078 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306079 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080
6081 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306082
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006083 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306084 {
6085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6086 FL("already beacon info added to session(%d)"),
6087 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006088 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306089 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006090
6091 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6092
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306093 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006094 {
6095 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306096 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006097 return -EINVAL;
6098 }
6099 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006101 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6102#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6103 params->channel, params->channel_type);
6104#else
6105 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6106#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006107#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006108 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6109 params->ssid_len, params->hidden_ssid);
6110 }
6111
6112 EXIT();
6113 return status;
6114}
6115
6116
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306117static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006118 struct net_device *dev,
6119 struct cfg80211_beacon_data *params)
6120{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik10728722014-05-14 16:20:25 +05306122 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306123 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006124
6125 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05306126 if (NULL == pAdapter)
6127 {
6128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6129 "%s: HDD adapter context is Null", __func__);
6130 return -ENODEV;
6131 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6133 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6134 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006135 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006136 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306137
6138 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6139 status = wlan_hdd_validate_context(pHddCtx);
6140
6141 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6144 "%s: HDD context is not valid", __func__);
6145 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006146 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006147
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306148 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006149 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306150 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006151 {
6152 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306153
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006154 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306155
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006156 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306157 {
6158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6159 FL("session(%d) beacon data points to NULL"),
6160 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006161 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306162 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006163
6164 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6165
6166 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306167 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006168 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006169 return -EINVAL;
6170 }
6171
6172 pAdapter->sessionCtx.ap.beacon = new;
6173
6174 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6175 }
6176
6177 EXIT();
6178 return status;
6179}
6180
6181#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6182
Jeff Johnson295189b2012-06-20 16:38:30 -07006183
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306184static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 struct net_device *dev,
6186 struct bss_parameters *params)
6187{
6188 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6189
6190 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05306191 if (NULL == pAdapter)
6192 {
6193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6194 "%s: HDD adapter context is Null", __func__);
6195 return -ENODEV;
6196 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306197 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6198 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6199 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6201 __func__, hdd_device_modetoString(pAdapter->device_mode),
6202 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006203
6204 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306206 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 {
6208 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6209 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306210 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 {
6212 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 }
6215
6216 EXIT();
6217 return 0;
6218}
6219
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306220static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6221 struct net_device *dev,
6222 struct bss_parameters *params)
6223{
6224 int ret;
6225
6226 vos_ssr_protect(__func__);
6227 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6228 vos_ssr_unprotect(__func__);
6229
6230 return ret;
6231}
Kiet Lam10841362013-11-01 11:36:50 +05306232/* FUNCTION: wlan_hdd_change_country_code_cd
6233* to wait for contry code completion
6234*/
6235void* wlan_hdd_change_country_code_cb(void *pAdapter)
6236{
6237 hdd_adapter_t *call_back_pAdapter = pAdapter;
6238 complete(&call_back_pAdapter->change_country_code);
6239 return NULL;
6240}
6241
Jeff Johnson295189b2012-06-20 16:38:30 -07006242/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306243 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6245 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306246int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 struct net_device *ndev,
6248 enum nl80211_iftype type,
6249 u32 *flags,
6250 struct vif_params *params
6251 )
6252{
6253 struct wireless_dev *wdev;
6254 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006255 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006256 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 tCsrRoamProfile *pRoamProfile = NULL;
6258 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306259 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 eMib_dot11DesiredBssType connectedBssType;
6261 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306262 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006263
6264 ENTER();
6265
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306266 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006267 {
6268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6269 "%s: Adapter context is null", __func__);
6270 return VOS_STATUS_E_FAILURE;
6271 }
6272
6273 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6274 if (!pHddCtx)
6275 {
6276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6277 "%s: HDD context is null", __func__);
6278 return VOS_STATUS_E_FAILURE;
6279 }
6280
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6282 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6283 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306284 status = wlan_hdd_validate_context(pHddCtx);
6285
6286 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6289 "%s: HDD context is not valid", __func__);
6290 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 }
6292
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6294 __func__, hdd_device_modetoString(pAdapter->device_mode),
6295 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006296
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306297 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 wdev = ndev->ieee80211_ptr;
6299
6300#ifdef WLAN_BTAMP_FEATURE
6301 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6302 (NL80211_IFTYPE_ADHOC == type)||
6303 (NL80211_IFTYPE_AP == type)||
6304 (NL80211_IFTYPE_P2P_GO == type))
6305 {
6306 pHddCtx->isAmpAllowed = VOS_FALSE;
6307 // stop AMP traffic
6308 status = WLANBAP_StopAmp();
6309 if(VOS_STATUS_SUCCESS != status )
6310 {
6311 pHddCtx->isAmpAllowed = VOS_TRUE;
6312 hddLog(VOS_TRACE_LEVEL_FATAL,
6313 "%s: Failed to stop AMP", __func__);
6314 return -EINVAL;
6315 }
6316 }
6317#endif //WLAN_BTAMP_FEATURE
6318 /* Reset the current device mode bit mask*/
6319 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6320
6321 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006323 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 )
6325 {
6326 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006327 if (!pWextState)
6328 {
6329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6330 "%s: pWextState is null", __func__);
6331 return VOS_STATUS_E_FAILURE;
6332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 pRoamProfile = &pWextState->roamProfile;
6334 LastBSSType = pRoamProfile->BSSType;
6335
6336 switch (type)
6337 {
6338 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 hddLog(VOS_TRACE_LEVEL_INFO,
6341 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6342 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006343#ifdef WLAN_FEATURE_11AC
6344 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6345 {
6346 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6347 }
6348#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306349 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006350 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006352 //Check for sub-string p2p to confirm its a p2p interface
6353 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306354 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006355 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6356 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6357 }
6358 else
6359 {
6360 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006362 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306363#ifdef FEATURE_WLAN_TDLS
6364 /* The open adapter for the p2p shall skip initializations in
6365 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6366 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6367 * tdls_init when the change_iface sets the device mode to
6368 * WLAN_HDD_P2P_CLIENT.
6369 */
6370
6371 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6372 {
6373 if (0 != wlan_hdd_tdls_init (pAdapter))
6374 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306375 hddLog(VOS_TRACE_LEVEL_ERROR,
6376 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306377 return -EINVAL;
6378 }
6379 }
6380#endif
6381
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 break;
6383 case NL80211_IFTYPE_ADHOC:
6384 hddLog(VOS_TRACE_LEVEL_INFO,
6385 "%s: setting interface Type to ADHOC", __func__);
6386 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6387 pRoamProfile->phyMode =
6388 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006389 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 wdev->iftype = type;
6391 break;
6392
6393 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 {
6396 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6397 "%s: setting interface Type to %s", __func__,
6398 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6399
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006400 //Cancel any remain on channel for GO mode
6401 if (NL80211_IFTYPE_P2P_GO == type)
6402 {
6403 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6404 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006405 if (NL80211_IFTYPE_AP == type)
6406 {
6407 /* As Loading WLAN Driver one interface being created for p2p device
6408 * address. This will take one HW STA and the max number of clients
6409 * that can connect to softAP will be reduced by one. so while changing
6410 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6411 * interface as it is not required in SoftAP mode.
6412 */
6413
6414 // Get P2P Adapter
6415 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6416
6417 if (pP2pAdapter)
6418 {
6419 hdd_stop_adapter(pHddCtx, pP2pAdapter);
6420 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6421 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6422 }
6423 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306424 //Disable IMPS & BMPS for SAP/GO
6425 if(VOS_STATUS_E_FAILURE ==
6426 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6427 {
6428 //Fail to Exit BMPS
6429 VOS_ASSERT(0);
6430 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306431#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006432
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306433 /* A Mutex Lock is introduced while changing the mode to
6434 * protect the concurrent access for the Adapters by TDLS
6435 * module.
6436 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306437 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 //De-init the adapter.
6440 hdd_stop_adapter( pHddCtx, pAdapter );
6441 hdd_deinit_adapter( pHddCtx, pAdapter );
6442 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6444 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306445#ifdef FEATURE_WLAN_TDLS
6446 mutex_unlock(&pHddCtx->tdls_lock);
6447#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006448 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6449 (pConfig->apRandomBssidEnabled))
6450 {
6451 /* To meet Android requirements create a randomized
6452 MAC address of the form 02:1A:11:Fx:xx:xx */
6453 get_random_bytes(&ndev->dev_addr[3], 3);
6454 ndev->dev_addr[0] = 0x02;
6455 ndev->dev_addr[1] = 0x1A;
6456 ndev->dev_addr[2] = 0x11;
6457 ndev->dev_addr[3] |= 0xF0;
6458 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6459 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006460 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6461 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006462 }
6463
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 hdd_set_ap_ops( pAdapter->dev );
6465
Kiet Lam10841362013-11-01 11:36:50 +05306466 /* This is for only SAP mode where users can
6467 * control country through ini.
6468 * P2P GO follows station country code
6469 * acquired during the STA scanning. */
6470 if((NL80211_IFTYPE_AP == type) &&
6471 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6472 {
6473 int status = 0;
6474 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6475 "%s: setting country code from INI ", __func__);
6476 init_completion(&pAdapter->change_country_code);
6477 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6478 (void *)(tSmeChangeCountryCallback)
6479 wlan_hdd_change_country_code_cb,
6480 pConfig->apCntryCode, pAdapter,
6481 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306482 eSIR_FALSE,
6483 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306484 if (eHAL_STATUS_SUCCESS == status)
6485 {
6486 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306487 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306488 &pAdapter->change_country_code,
6489 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306490 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306491 {
6492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306493 FL("SME Timed out while setting country code %ld"),
6494 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006495
6496 if (pHddCtx->isLogpInProgress)
6497 {
6498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6499 "%s: LOGP in Progress. Ignore!!!", __func__);
6500 return -EAGAIN;
6501 }
Kiet Lam10841362013-11-01 11:36:50 +05306502 }
6503 }
6504 else
6505 {
6506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006507 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306508 return -EINVAL;
6509 }
6510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 status = hdd_init_ap_mode(pAdapter);
6512 if(status != VOS_STATUS_SUCCESS)
6513 {
6514 hddLog(VOS_TRACE_LEVEL_FATAL,
6515 "%s: Error initializing the ap mode", __func__);
6516 return -EINVAL;
6517 }
6518 hdd_set_conparam(1);
6519
Jeff Johnson295189b2012-06-20 16:38:30 -07006520 /*interface type changed update in wiphy structure*/
6521 if(wdev)
6522 {
6523 wdev->iftype = type;
6524 pHddCtx->change_iface = type;
6525 }
6526 else
6527 {
6528 hddLog(VOS_TRACE_LEVEL_ERROR,
6529 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6530 return -EINVAL;
6531 }
6532 goto done;
6533 }
6534
6535 default:
6536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6537 __func__);
6538 return -EOPNOTSUPP;
6539 }
6540 }
6541 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 )
6544 {
6545 switch(type)
6546 {
6547 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306550#ifdef FEATURE_WLAN_TDLS
6551
6552 /* A Mutex Lock is introduced while changing the mode to
6553 * protect the concurrent access for the Adapters by TDLS
6554 * module.
6555 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306556 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306557#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07006558 hdd_stop_adapter( pHddCtx, pAdapter );
6559 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006561 //Check for sub-string p2p to confirm its a p2p interface
6562 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006563 {
6564 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6565 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6566 }
6567 else
6568 {
6569 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006570 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 hdd_set_conparam(0);
6573 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6575 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306576#ifdef FEATURE_WLAN_TDLS
6577 mutex_unlock(&pHddCtx->tdls_lock);
6578#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306579 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 if( VOS_STATUS_SUCCESS != status )
6581 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006582 /* In case of JB, for P2P-GO, only change interface will be called,
6583 * This is the right place to enable back bmps_imps()
6584 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306585 if (pHddCtx->hdd_wlan_suspended)
6586 {
6587 hdd_set_pwrparams(pHddCtx);
6588 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006589 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 goto done;
6591 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6595 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 goto done;
6597 default:
6598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6599 __func__);
6600 return -EOPNOTSUPP;
6601
6602 }
6603
6604 }
6605 else
6606 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306607 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6608 __func__, hdd_device_modetoString(pAdapter->device_mode),
6609 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 return -EOPNOTSUPP;
6611 }
6612
6613
6614 if(pRoamProfile)
6615 {
6616 if ( LastBSSType != pRoamProfile->BSSType )
6617 {
6618 /*interface type changed update in wiphy structure*/
6619 wdev->iftype = type;
6620
6621 /*the BSS mode changed, We need to issue disconnect
6622 if connected or in IBSS disconnect state*/
6623 if ( hdd_connGetConnectedBssType(
6624 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6625 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6626 {
6627 /*need to issue a disconnect to CSR.*/
6628 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6629 if( eHAL_STATUS_SUCCESS ==
6630 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6631 pAdapter->sessionId,
6632 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6633 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306634 ret = wait_for_completion_interruptible_timeout(
6635 &pAdapter->disconnect_comp_var,
6636 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6637 if (ret <= 0)
6638 {
6639 hddLog(VOS_TRACE_LEVEL_ERROR,
6640 FL("wait on disconnect_comp_var failed %ld"), ret);
6641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 }
6643 }
6644 }
6645 }
6646
6647done:
6648 /*set bitmask based on updated value*/
6649 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006650
6651 /* Only STA mode support TM now
6652 * all other mode, TM feature should be disabled */
6653 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6654 (~VOS_STA & pHddCtx->concurrency_mode) )
6655 {
6656 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6657 }
6658
Jeff Johnson295189b2012-06-20 16:38:30 -07006659#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306660 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6662 {
6663 //we are ok to do AMP
6664 pHddCtx->isAmpAllowed = VOS_TRUE;
6665 }
6666#endif //WLAN_BTAMP_FEATURE
6667 EXIT();
6668 return 0;
6669}
6670
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306671/*
6672 * FUNCTION: wlan_hdd_cfg80211_change_iface
6673 * wrapper function to protect the actual implementation from SSR.
6674 */
6675int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6676 struct net_device *ndev,
6677 enum nl80211_iftype type,
6678 u32 *flags,
6679 struct vif_params *params
6680 )
6681{
6682 int ret;
6683
6684 vos_ssr_protect(__func__);
6685 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6686 vos_ssr_unprotect(__func__);
6687
6688 return ret;
6689}
6690
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006691#ifdef FEATURE_WLAN_TDLS
6692static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6693 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6694{
6695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6696 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6697 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006698 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306699 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306700 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006701
6702 ENTER();
6703
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306704 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006705 {
6706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6707 "Invalid arguments");
6708 return -EINVAL;
6709 }
Hoonki Lee27511902013-03-14 18:19:06 -07006710
6711 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6712 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6713 {
6714 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6715 "%s: TDLS mode is disabled OR not enabled in FW."
6716 MAC_ADDRESS_STR " Request declined.",
6717 __func__, MAC_ADDR_ARRAY(mac));
6718 return -ENOTSUPP;
6719 }
6720
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006721 if (pHddCtx->isLogpInProgress)
6722 {
6723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6724 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006725 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006726 return -EBUSY;
6727 }
6728
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306729 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006730
6731 if ( NULL == pTdlsPeer ) {
6732 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6733 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6734 __func__, MAC_ADDR_ARRAY(mac), update);
6735 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006736 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006737
6738 /* in add station, we accept existing valid staId if there is */
6739 if ((0 == update) &&
6740 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6741 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006742 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006743 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006744 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006745 " link_status %d. staId %d. add station ignored.",
6746 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6747 return 0;
6748 }
6749 /* in change station, we accept only when staId is valid */
6750 if ((1 == update) &&
6751 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6752 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6753 {
6754 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6755 "%s: " MAC_ADDRESS_STR
6756 " link status %d. staId %d. change station %s.",
6757 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6758 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6759 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006760 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006761
6762 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306763 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006764 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6766 "%s: " MAC_ADDRESS_STR
6767 " TDLS setup is ongoing. Request declined.",
6768 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006769 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006770 }
6771
6772 /* first to check if we reached to maximum supported TDLS peer.
6773 TODO: for now, return -EPERM looks working fine,
6774 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306775 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6776 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006777 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6779 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306780 " TDLS Max peer already connected. Request declined."
6781 " Num of peers (%d), Max allowed (%d).",
6782 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6783 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006784 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006785 }
6786 else
6787 {
6788 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306789 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006790 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006791 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6793 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6794 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006795 return -EPERM;
6796 }
6797 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006798 if (0 == update)
6799 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006800
Jeff Johnsond75fe012013-04-06 10:53:06 -07006801 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306802 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006803 {
6804 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6805 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006806 if(StaParams->htcap_present)
6807 {
6808 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6809 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6810 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6811 "ht_capa->extended_capabilities: %0x",
6812 StaParams->HTCap.extendedHtCapInfo);
6813 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006814 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6815 "params->capability: %0x",StaParams->capability);
6816 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006817 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006818 if(StaParams->vhtcap_present)
6819 {
6820 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6821 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6822 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6823 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6824 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006825 {
6826 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006828 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6829 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6830 "[%d]: %x ", i, StaParams->supported_rates[i]);
6831 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006832 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306833 else if ((1 == update) && (NULL == StaParams))
6834 {
6835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6836 "%s : update is true, but staParams is NULL. Error!", __func__);
6837 return -EPERM;
6838 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006839
6840 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6841
6842 if (!update)
6843 {
6844 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6845 pAdapter->sessionId, mac);
6846 }
6847 else
6848 {
6849 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6850 pAdapter->sessionId, mac, StaParams);
6851 }
6852
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306853 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006854 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6855
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306856 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006857 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306859 "%s: timeout waiting for tdls add station indication %ld",
6860 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006861 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006862 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306863
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006864 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6865 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006867 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006868 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006869 }
6870
6871 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006872
6873error:
6874 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6875 return -EPERM;
6876
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006877}
6878#endif
6879
Jeff Johnson295189b2012-06-20 16:38:30 -07006880static int wlan_hdd_change_station(struct wiphy *wiphy,
6881 struct net_device *dev,
6882 u8 *mac,
6883 struct station_parameters *params)
6884{
6885 VOS_STATUS status = VOS_STATUS_SUCCESS;
6886 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306887 hdd_context_t *pHddCtx;
6888 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006890#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006891 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006892 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306893 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006894#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006895 ENTER();
6896
Gopichand Nakkala29149562013-05-10 21:43:41 +05306897 if ((NULL == pAdapter))
6898 {
Sushant Kaushik10728722014-05-14 16:20:25 +05306899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306900 "invalid adapter ");
6901 return -EINVAL;
6902 }
6903
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306904 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6905 TRACE_CODE_HDD_CHANGE_STATION,
6906 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306907 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6908 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6909
6910 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6911 {
6912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6913 "invalid HDD state or HDD station context");
6914 return -EINVAL;
6915 }
6916
6917 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006918 {
6919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6920 "%s:LOGP in Progress. Ignore!!!", __func__);
6921 return -EAGAIN;
6922 }
6923
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6925
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006926 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6927 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006929 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 WLANTL_STA_AUTHENTICATED);
6933
Gopichand Nakkala29149562013-05-10 21:43:41 +05306934 if (status != VOS_STATUS_SUCCESS)
6935 {
6936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6937 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6938 return -EINVAL;
6939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 }
6941 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006942 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6943 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306944#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006945 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6946 StaParams.capability = params->capability;
6947 StaParams.uapsd_queues = params->uapsd_queues;
6948 StaParams.max_sp = params->max_sp;
6949
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306950 /* Convert (first channel , number of channels) tuple to
6951 * the total list of channels. This goes with the assumption
6952 * that if the first channel is < 14, then the next channels
6953 * are an incremental of 1 else an incremental of 4 till the number
6954 * of channels.
6955 */
6956 if (0 != params->supported_channels_len) {
6957 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6958 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6959 {
6960 int wifi_chan_index;
6961 StaParams.supported_channels[j] = params->supported_channels[i];
6962 wifi_chan_index =
6963 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6964 no_of_channels = params->supported_channels[i+1];
6965 for(k=1; k <= no_of_channels; k++)
6966 {
6967 StaParams.supported_channels[j+1] =
6968 StaParams.supported_channels[j] + wifi_chan_index;
6969 j+=1;
6970 }
6971 }
6972 StaParams.supported_channels_len = j;
6973 }
6974 vos_mem_copy(StaParams.supported_oper_classes,
6975 params->supported_oper_classes,
6976 params->supported_oper_classes_len);
6977 StaParams.supported_oper_classes_len =
6978 params->supported_oper_classes_len;
6979
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006980 if (0 != params->ext_capab_len)
6981 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
6982 sizeof(StaParams.extn_capability));
6983
6984 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006985 {
6986 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006987 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006988 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006989
6990 StaParams.supported_rates_len = params->supported_rates_len;
6991
6992 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
6993 * The supported_rates array , for all the structures propogating till Add Sta
6994 * to the firmware has to be modified , if the supplicant (ieee80211) is
6995 * modified to send more rates.
6996 */
6997
6998 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
6999 */
7000 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7001 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7002
7003 if (0 != StaParams.supported_rates_len) {
7004 int i = 0;
7005 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7006 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007008 "Supported Rates with Length %d", StaParams.supported_rates_len);
7009 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007011 "[%d]: %0x", i, StaParams.supported_rates[i]);
7012 }
7013
7014 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007015 {
7016 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007017 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007018 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007019
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007020 if (0 != params->ext_capab_len ) {
7021 /*Define A Macro : TODO Sunil*/
7022 if ((1<<4) & StaParams.extn_capability[3]) {
7023 isBufSta = 1;
7024 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307025 /* TDLS Channel Switching Support */
7026 if ((1<<6) & StaParams.extn_capability[3]) {
7027 isOffChannelSupported = 1;
7028 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007029 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307030 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7031 &StaParams, isBufSta,
7032 isOffChannelSupported);
7033
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307034 if (VOS_STATUS_SUCCESS != status) {
7035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7036 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7037 return -EINVAL;
7038 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007039 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7040
7041 if (VOS_STATUS_SUCCESS != status) {
7042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7043 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7044 return -EINVAL;
7045 }
7046 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007047#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307048 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007049 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 return status;
7051}
7052
7053/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307054 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 * This function is used to initialize the key information
7056 */
7057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307058static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 struct net_device *ndev,
7060 u8 key_index, bool pairwise,
7061 const u8 *mac_addr,
7062 struct key_params *params
7063 )
7064#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307065static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007066 struct net_device *ndev,
7067 u8 key_index, const u8 *mac_addr,
7068 struct key_params *params
7069 )
7070#endif
7071{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 tCsrRoamSetKey setKey;
7074 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307075 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007076 v_U32_t roamId= 0xFF;
7077 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 hdd_hostapd_state_t *pHostapdState;
7079 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007080 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307081 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007082
7083 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05307084 if (NULL == pAdapter)
7085 {
7086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7087 "%s: HDD adapter context is Null", __func__);
7088 return -ENODEV;
7089 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7091 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7092 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7094 status = wlan_hdd_validate_context(pHddCtx);
7095
7096 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7099 "%s: HDD context is not valid", __func__);
7100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007101 }
7102
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7104 __func__, hdd_device_modetoString(pAdapter->device_mode),
7105 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007106
7107 if (CSR_MAX_NUM_KEY <= key_index)
7108 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 key_index);
7111
7112 return -EINVAL;
7113 }
7114
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007115 if (CSR_MAX_KEY_LEN < params->key_len)
7116 {
7117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7118 params->key_len);
7119
7120 return -EINVAL;
7121 }
7122
7123 hddLog(VOS_TRACE_LEVEL_INFO,
7124 "%s: called with key index = %d & key length %d",
7125 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007126
7127 /*extract key idx, key len and key*/
7128 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7129 setKey.keyId = key_index;
7130 setKey.keyLength = params->key_len;
7131 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7132
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007133 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 {
7135 case WLAN_CIPHER_SUITE_WEP40:
7136 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7137 break;
7138
7139 case WLAN_CIPHER_SUITE_WEP104:
7140 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7141 break;
7142
7143 case WLAN_CIPHER_SUITE_TKIP:
7144 {
7145 u8 *pKey = &setKey.Key[0];
7146 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7147
7148 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7149
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007150 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007151
7152 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007153 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 |--------------|----------|----------|
7155 <---16bytes---><--8bytes--><--8bytes-->
7156
7157 */
7158 /*Sme expects the 32 bytes key to be in the below order
7159
7160 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007161 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 |--------------|----------|----------|
7163 <---16bytes---><--8bytes--><--8bytes-->
7164 */
7165 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007166 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007167
7168 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007169 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007170
7171 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007172 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007173
7174
7175 break;
7176 }
7177
7178 case WLAN_CIPHER_SUITE_CCMP:
7179 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7180 break;
7181
7182#ifdef FEATURE_WLAN_WAPI
7183 case WLAN_CIPHER_SUITE_SMS4:
7184 {
7185 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7186 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7187 params->key, params->key_len);
7188 return 0;
7189 }
7190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007191
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007192#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 case WLAN_CIPHER_SUITE_KRK:
7194 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7195 break;
7196#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007197
7198#ifdef WLAN_FEATURE_11W
7199 case WLAN_CIPHER_SUITE_AES_CMAC:
7200 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007201 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007202#endif
7203
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 __func__, params->cipher);
7207 return -EOPNOTSUPP;
7208 }
7209
7210 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7211 __func__, setKey.encType);
7212
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007213 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7215 (!pairwise)
7216#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007217 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007218#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007219 )
7220 {
7221 /* set group key*/
7222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7223 "%s- %d: setting Broadcast key",
7224 __func__, __LINE__);
7225 setKey.keyDirection = eSIR_RX_ONLY;
7226 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7227 }
7228 else
7229 {
7230 /* set pairwise key*/
7231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7232 "%s- %d: setting pairwise key",
7233 __func__, __LINE__);
7234 setKey.keyDirection = eSIR_TX_RX;
7235 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7236 }
7237 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7238 {
7239 setKey.keyDirection = eSIR_TX_RX;
7240 /*Set the group key*/
7241 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7242 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007243
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007244 if ( 0 != status )
7245 {
7246 hddLog(VOS_TRACE_LEVEL_ERROR,
7247 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7248 return -EINVAL;
7249 }
7250 /*Save the keys here and call sme_RoamSetKey for setting
7251 the PTK after peer joins the IBSS network*/
7252 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7253 &setKey, sizeof(tCsrRoamSetKey));
7254 return status;
7255 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307256 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7257 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7258 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007260 if( pHostapdState->bssState == BSS_START )
7261 {
c_hpothu7c55da62014-01-23 18:34:02 +05307262 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7263 vos_status = wlan_hdd_check_ula_done(pAdapter);
7264
7265 if ( vos_status != VOS_STATUS_SUCCESS )
7266 {
7267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7268 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7269 __LINE__, vos_status );
7270
7271 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7272
7273 return -EINVAL;
7274 }
7275
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7277
7278 if ( status != eHAL_STATUS_SUCCESS )
7279 {
7280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7281 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7282 __LINE__, status );
7283 }
7284 }
7285
7286 /* Saving WEP keys */
7287 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7288 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7289 {
7290 //Save the wep key in ap context. Issue setkey after the BSS is started.
7291 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7292 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7293 }
7294 else
7295 {
7296 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007297 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7299 }
7300 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007301 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7302 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
7304 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7305 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7306
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7308 if (!pairwise)
7309#else
7310 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7311#endif
7312 {
7313 /* set group key*/
7314 if (pHddStaCtx->roam_info.deferKeyComplete)
7315 {
7316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7317 "%s- %d: Perform Set key Complete",
7318 __func__, __LINE__);
7319 hdd_PerformRoamSetKeyComplete(pAdapter);
7320 }
7321 }
7322
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7324
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007325 pWextState->roamProfile.Keys.defaultIndex = key_index;
7326
7327
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007328 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 params->key, params->key_len);
7330
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307331
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307334 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307336 __func__, setKey.peerMac[0], setKey.peerMac[1],
7337 setKey.peerMac[2], setKey.peerMac[3],
7338 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 setKey.keyDirection);
7340
7341 vos_status = wlan_hdd_check_ula_done(pAdapter);
7342
7343 if ( vos_status != VOS_STATUS_SUCCESS )
7344 {
7345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7346 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7347 __LINE__, vos_status );
7348
7349 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7350
7351 return -EINVAL;
7352
7353 }
7354
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007355#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307356 /* The supplicant may attempt to set the PTK once pre-authentication
7357 is done. Save the key in the UMAC and include it in the ADD BSS
7358 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007359 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307360 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007361 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307362 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7363 "%s: Update PreAuth Key success", __func__);
7364 return 0;
7365 }
7366 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7367 {
7368 hddLog(VOS_TRACE_LEVEL_ERROR,
7369 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307370 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007371 }
7372#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007373
7374 /* issue set key request to SME*/
7375 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7376 pAdapter->sessionId, &setKey, &roamId );
7377
7378 if ( 0 != status )
7379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7382 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7383 return -EINVAL;
7384 }
7385
7386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307387 /* in case of IBSS as there was no information available about WEP keys during
7388 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307390 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7391 !( ( IW_AUTH_KEY_MGMT_802_1X
7392 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007393 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7394 )
7395 &&
7396 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7397 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7398 )
7399 )
7400 {
7401 setKey.keyDirection = eSIR_RX_ONLY;
7402 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7403
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307404 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307406 __func__, setKey.peerMac[0], setKey.peerMac[1],
7407 setKey.peerMac[2], setKey.peerMac[3],
7408 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 setKey.keyDirection);
7410
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307411 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 pAdapter->sessionId, &setKey, &roamId );
7413
7414 if ( 0 != status )
7415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307416 hddLog(VOS_TRACE_LEVEL_ERROR,
7417 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 __func__, status);
7419 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7420 return -EINVAL;
7421 }
7422 }
7423 }
7424
7425 return 0;
7426}
7427
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7429static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7430 struct net_device *ndev,
7431 u8 key_index, bool pairwise,
7432 const u8 *mac_addr,
7433 struct key_params *params
7434 )
7435#else
7436static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7437 struct net_device *ndev,
7438 u8 key_index, const u8 *mac_addr,
7439 struct key_params *params
7440 )
7441#endif
7442{
7443 int ret;
7444 vos_ssr_protect(__func__);
7445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7446 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7447 mac_addr, params);
7448#else
7449 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7450 params);
7451#endif
7452 vos_ssr_unprotect(__func__);
7453
7454 return ret;
7455}
7456
Jeff Johnson295189b2012-06-20 16:38:30 -07007457/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307458 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 * This function is used to get the key information
7460 */
7461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307462static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307465 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 const u8 *mac_addr, void *cookie,
7467 void (*callback)(void *cookie, struct key_params*)
7468 )
7469#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307470static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307471 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 struct net_device *ndev,
7473 u8 key_index, const u8 *mac_addr, void *cookie,
7474 void (*callback)(void *cookie, struct key_params*)
7475 )
7476#endif
7477{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushik10728722014-05-14 16:20:25 +05307479 hdd_wext_state_t *pWextState= NULL;
7480 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 struct key_params params;
7482
7483 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484
Sushant Kaushik10728722014-05-14 16:20:25 +05307485 if (NULL == pAdapter)
7486 {
7487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7488 "%s: HDD adapter context is Null", __func__);
7489 return -ENODEV;
7490 }
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7492 __func__, hdd_device_modetoString(pAdapter->device_mode),
7493 pAdapter->device_mode);
Sushant Kaushik10728722014-05-14 16:20:25 +05307494 pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7495 pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 memset(&params, 0, sizeof(params));
7497
7498 if (CSR_MAX_NUM_KEY <= key_index)
7499 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007503
7504 switch(pRoamProfile->EncryptionType.encryptionType[0])
7505 {
7506 case eCSR_ENCRYPT_TYPE_NONE:
7507 params.cipher = IW_AUTH_CIPHER_NONE;
7508 break;
7509
7510 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7511 case eCSR_ENCRYPT_TYPE_WEP40:
7512 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7513 break;
7514
7515 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7516 case eCSR_ENCRYPT_TYPE_WEP104:
7517 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7518 break;
7519
7520 case eCSR_ENCRYPT_TYPE_TKIP:
7521 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7522 break;
7523
7524 case eCSR_ENCRYPT_TYPE_AES:
7525 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7526 break;
7527
7528 default:
7529 params.cipher = IW_AUTH_CIPHER_NONE;
7530 break;
7531 }
c_hpothuaaf19692014-05-17 17:01:48 +05307532 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7533 TRACE_CODE_HDD_CFG80211_GET_KEY,
7534 pAdapter->sessionId, params.cipher));
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7536 params.seq_len = 0;
7537 params.seq = NULL;
7538 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7539 callback(cookie, &params);
7540 return 0;
7541}
7542
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307543#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7544static int wlan_hdd_cfg80211_get_key(
7545 struct wiphy *wiphy,
7546 struct net_device *ndev,
7547 u8 key_index, bool pairwise,
7548 const u8 *mac_addr, void *cookie,
7549 void (*callback)(void *cookie, struct key_params*)
7550 )
7551#else
7552static int wlan_hdd_cfg80211_get_key(
7553 struct wiphy *wiphy,
7554 struct net_device *ndev,
7555 u8 key_index, const u8 *mac_addr, void *cookie,
7556 void (*callback)(void *cookie, struct key_params*)
7557 )
7558#endif
7559{
7560 int ret;
7561
7562 vos_ssr_protect(__func__);
7563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7564 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7565 mac_addr, cookie, callback);
7566#else
7567 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7568 callback);
7569#endif
7570 vos_ssr_unprotect(__func__);
7571
7572 return ret;
7573}
7574
Jeff Johnson295189b2012-06-20 16:38:30 -07007575/*
7576 * FUNCTION: wlan_hdd_cfg80211_del_key
7577 * This function is used to delete the key information
7578 */
7579#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307582 u8 key_index,
7583 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 const u8 *mac_addr
7585 )
7586#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307587static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 struct net_device *ndev,
7589 u8 key_index,
7590 const u8 *mac_addr
7591 )
7592#endif
7593{
7594 int status = 0;
7595
7596 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307597 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007598 //it is observed that this is invalidating peer
7599 //key index whenever re-key is done. This is affecting data link.
7600 //It should be ok to ignore del_key.
7601#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7603 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007604 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7605 tCsrRoamSetKey setKey;
7606 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307607
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 ENTER();
7609
7610 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7611 __func__,pAdapter->device_mode);
7612
7613 if (CSR_MAX_NUM_KEY <= key_index)
7614 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 key_index);
7617
7618 return -EINVAL;
7619 }
7620
7621 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7622 setKey.keyId = key_index;
7623
7624 if (mac_addr)
7625 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7626 else
7627 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7628
7629 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7630
7631 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307633 )
7634 {
7635
7636 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7638 if( pHostapdState->bssState == BSS_START)
7639 {
7640 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307641
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 if ( status != eHAL_STATUS_SUCCESS )
7643 {
7644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7646 __LINE__, status );
7647 }
7648 }
7649 }
7650 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307651 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 )
7653 {
7654 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7655
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307656 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7657
7658 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307660 __func__, setKey.peerMac[0], setKey.peerMac[1],
7661 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307663 if(pAdapter->sessionCtx.station.conn_info.connState ==
7664 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307666 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307668
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 if ( 0 != status )
7670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307671 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 "%s: sme_RoamSetKey failure, returned %d",
7673 __func__, status);
7674 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7675 return -EINVAL;
7676 }
7677 }
7678 }
7679#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007680 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 return status;
7682}
7683
7684/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307685 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 * This function is used to set the default tx key index
7687 */
7688#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307689static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 struct net_device *ndev,
7691 u8 key_index,
7692 bool unicast, bool multicast)
7693#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307694static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 struct net_device *ndev,
7696 u8 key_index)
7697#endif
7698{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307700 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307701 hdd_wext_state_t *pWextState;
7702 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307703 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007704
7705 ENTER();
7706
Gopichand Nakkala29149562013-05-10 21:43:41 +05307707 if ((NULL == pAdapter))
7708 {
Sushant Kaushik10728722014-05-14 16:20:25 +05307709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307710 "invalid adapter");
7711 return -EINVAL;
7712 }
7713
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307714 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7715 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7716 pAdapter->sessionId, key_index));
7717
Gopichand Nakkala29149562013-05-10 21:43:41 +05307718 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7719 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7720
7721 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7722 {
7723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7724 "invalid Wext state or HDD context");
7725 return -EINVAL;
7726 }
7727
Arif Hussain6d2a3322013-11-17 19:50:10 -08007728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307730
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 if (CSR_MAX_NUM_KEY <= key_index)
7732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 key_index);
7735
7736 return -EINVAL;
7737 }
7738
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307739 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7740 status = wlan_hdd_validate_context(pHddCtx);
7741
7742 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007743 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7745 "%s: HDD context is not valid", __func__);
7746 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007747 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307748
Jeff Johnson295189b2012-06-20 16:38:30 -07007749 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307751 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307753 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007754 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307755 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007756 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307758 {
7759 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307761
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 tCsrRoamSetKey setKey;
7763 v_U32_t roamId= 0xFF;
7764 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307765
7766 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307768
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 Keys->defaultIndex = (u8)key_index;
7770 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7771 setKey.keyId = key_index;
7772 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307773
7774 vos_mem_copy(&setKey.Key[0],
7775 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307777
Gopichand Nakkala29149562013-05-10 21:43:41 +05307778 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307779
7780 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 &pHddStaCtx->conn_info.bssId[0],
7782 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307783
Gopichand Nakkala29149562013-05-10 21:43:41 +05307784 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7785 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7786 eCSR_ENCRYPT_TYPE_WEP104)
7787 {
7788 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7789 even though ap is configured for WEP-40 encryption. In this canse the key length
7790 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7791 type(104) and switching encryption type to 40*/
7792 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7793 eCSR_ENCRYPT_TYPE_WEP40;
7794 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7795 eCSR_ENCRYPT_TYPE_WEP40;
7796 }
7797
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307798 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307802 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307804
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 if ( 0 != status )
7806 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307807 hddLog(VOS_TRACE_LEVEL_ERROR,
7808 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 status);
7810 return -EINVAL;
7811 }
7812 }
7813 }
7814
7815 /* In SoftAp mode setting key direction for default mode */
7816 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7817 {
7818 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7819 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7820 (eCSR_ENCRYPT_TYPE_AES !=
7821 pWextState->roamProfile.EncryptionType.encryptionType[0])
7822 )
7823 {
7824 /* Saving key direction for default key index to TX default */
7825 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7826 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7827 }
7828 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 return status;
7831}
7832
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307833#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7834static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7835 struct net_device *ndev,
7836 u8 key_index,
7837 bool unicast, bool multicast)
7838#else
7839static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7840 struct net_device *ndev,
7841 u8 key_index)
7842#endif
7843{
7844 int ret;
7845 vos_ssr_protect(__func__);
7846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7847 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7848 multicast);
7849#else
7850 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7851#endif
7852 vos_ssr_unprotect(__func__);
7853
7854 return ret;
7855}
7856
Jeff Johnson295189b2012-06-20 16:38:30 -07007857/*
7858 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7859 * This function is used to inform the BSS details to nl80211 interface.
7860 */
7861static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7862 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7863{
7864 struct net_device *dev = pAdapter->dev;
7865 struct wireless_dev *wdev = dev->ieee80211_ptr;
7866 struct wiphy *wiphy = wdev->wiphy;
7867 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7868 int chan_no;
7869 int ie_length;
7870 const char *ie;
7871 unsigned int freq;
7872 struct ieee80211_channel *chan;
7873 int rssi = 0;
7874 struct cfg80211_bss *bss = NULL;
7875
7876 ENTER();
7877
7878 if( NULL == pBssDesc )
7879 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007880 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 return bss;
7882 }
7883
7884 chan_no = pBssDesc->channelId;
7885 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7886 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7887
7888 if( NULL == ie )
7889 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 return bss;
7892 }
7893
7894#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7895 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7896 {
7897 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7898 }
7899 else
7900 {
7901 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7902 }
7903#else
7904 freq = ieee80211_channel_to_frequency(chan_no);
7905#endif
7906
7907 chan = __ieee80211_get_channel(wiphy, freq);
7908
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307909 if (!chan) {
7910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7911 return NULL;
7912 }
7913
Abhishek Singhaee43942014-06-16 18:55:47 +05307914 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007915
Abhishek Singhaee43942014-06-16 18:55:47 +05307916 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307917 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 pBssDesc->capabilityInfo,
7919 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307920 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007921}
7922
7923
7924
7925/*
7926 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7927 * This function is used to inform the BSS details to nl80211 interface.
7928 */
7929struct cfg80211_bss*
7930wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7931 tSirBssDescription *bss_desc
7932 )
7933{
7934 /*
7935 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7936 already exists in bss data base of cfg80211 for that particular BSS ID.
7937 Using cfg80211_inform_bss_frame to update the bss entry instead of
7938 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7939 now there is no possibility to get the mgmt(probe response) frame from PE,
7940 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7941 cfg80211_inform_bss_frame.
7942 */
7943 struct net_device *dev = pAdapter->dev;
7944 struct wireless_dev *wdev = dev->ieee80211_ptr;
7945 struct wiphy *wiphy = wdev->wiphy;
7946 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007947#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7948 qcom_ie_age *qie_age = NULL;
7949 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7950#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 const char *ie =
7954 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7955 unsigned int freq;
7956 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307957 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007958 struct cfg80211_bss *bss_status = NULL;
7959 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7960 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007961 hdd_context_t *pHddCtx;
7962 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007963#ifdef WLAN_OPEN_SOURCE
7964 struct timespec ts;
7965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
Wilson Yangf80a0542013-10-07 13:02:37 -07007967 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7968 status = wlan_hdd_validate_context(pHddCtx);
7969
7970 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307971 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007972 {
7973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7974 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7975 return NULL;
7976 }
7977
7978
7979 if (0 != status)
7980 {
7981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7982 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007983 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007984 }
7985
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307986 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007987 if (!mgmt)
7988 {
7989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7990 "%s: memory allocation failed ", __func__);
7991 return NULL;
7992 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007993
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07007995
7996#ifdef WLAN_OPEN_SOURCE
7997 /* Android does not want the timestamp from the frame.
7998 Instead it wants a monotonic increasing value */
7999 get_monotonic_boottime(&ts);
8000 mgmt->u.probe_resp.timestamp =
8001 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8002#else
8003 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8005 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008006
8007#endif
8008
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8010 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008011
8012#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8013 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8014 /* Assuming this is the last IE, copy at the end */
8015 ie_length -=sizeof(qcom_ie_age);
8016 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8017 qie_age->element_id = QCOM_VENDOR_IE_ID;
8018 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8019 qie_age->oui_1 = QCOM_OUI1;
8020 qie_age->oui_2 = QCOM_OUI2;
8021 qie_age->oui_3 = QCOM_OUI3;
8022 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8023 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8024#endif
8025
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308027 if (bss_desc->fProbeRsp)
8028 {
8029 mgmt->frame_control |=
8030 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8031 }
8032 else
8033 {
8034 mgmt->frame_control |=
8035 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8036 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008037
8038#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308039 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8041 {
8042 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308044 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8046
8047 {
8048 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8049 }
8050 else
8051 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8053 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 kfree(mgmt);
8055 return NULL;
8056 }
8057#else
8058 freq = ieee80211_channel_to_frequency(chan_no);
8059#endif
8060 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008061 /*when the band is changed on the fly using the GUI, three things are done
8062 * 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)
8063 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8064 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8065 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8066 * and discards the channels correponding to previous band and calls back with zero bss results.
8067 * 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
8068 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8069 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8070 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8071 * So drop the bss and continue to next bss.
8072 */
8073 if(chan == NULL)
8074 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008076 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008077 return NULL;
8078 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 * */
8082 if (( eConnectionState_Associated ==
8083 pAdapter->sessionCtx.station.conn_info.connState ) &&
8084 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8085 pAdapter->sessionCtx.station.conn_info.bssId,
8086 WNI_CFG_BSSID_LEN)))
8087 {
8088 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8089 rssi = (pAdapter->rssi * 100);
8090 }
8091 else
8092 {
8093 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8094 }
8095
Nirav Shah20ac06f2013-12-12 18:14:06 +05308096 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8097 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8098 chan->center_freq, (int)(rssi/100));
8099
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8101 frame_len, rssi, GFP_KERNEL);
8102 kfree(mgmt);
8103 return bss_status;
8104}
8105
8106/*
8107 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8108 * This function is used to update the BSS data base of CFG8011
8109 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308110struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 tCsrRoamInfo *pRoamInfo
8112 )
8113{
8114 tCsrRoamConnectedProfile roamProfile;
8115 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8116 struct cfg80211_bss *bss = NULL;
8117
8118 ENTER();
8119
8120 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8121 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8122
8123 if (NULL != roamProfile.pBssDesc)
8124 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308125 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 &roamProfile);
8127
8128 if (NULL == bss)
8129 {
8130 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8131 __func__);
8132 }
8133
8134 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8135 }
8136 else
8137 {
8138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8139 __func__);
8140 }
8141 return bss;
8142}
8143
8144/*
8145 * FUNCTION: wlan_hdd_cfg80211_update_bss
8146 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308147static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8148 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150{
Sushant Kaushik10728722014-05-14 16:20:25 +05308151 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008152 tCsrScanResultInfo *pScanResult;
8153 eHalStatus status = 0;
8154 tScanResultHandle pResult;
8155 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008156 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008157
8158 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +05308159 if (NULL == pAdapter)
8160 {
8161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8162 "%s: HDD adapter context is Null", __func__);
8163 return -ENODEV;
8164 }
8165 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8167 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8168 NO_SESSION, pAdapter->sessionId));
8169
Wilson Yangf80a0542013-10-07 13:02:37 -07008170 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8171
8172 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8175 "%s:LOGP in Progress. Ignore!!!",__func__);
8176 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008177 }
8178
Wilson Yangf80a0542013-10-07 13:02:37 -07008179
8180 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308181 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008182 {
8183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8184 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8185 return VOS_STATUS_E_PERM;
8186 }
8187
8188
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 /*
8190 * start getting scan results and populate cgf80211 BSS database
8191 */
8192 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8193
8194 /* no scan results */
8195 if (NULL == pResult)
8196 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8198 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 return status;
8200 }
8201
8202 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8203
8204 while (pScanResult)
8205 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308206 /*
8207 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8208 * entry already exists in bss data base of cfg80211 for that
8209 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8210 * bss entry instead of cfg80211_inform_bss, But this call expects
8211 * mgmt packet as input. As of now there is no possibility to get
8212 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 * ieee80211_mgmt(probe response) and passing to c
8214 * fg80211_inform_bss_frame.
8215 * */
8216
8217 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8218 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308219
Jeff Johnson295189b2012-06-20 16:38:30 -07008220
8221 if (NULL == bss_status)
8222 {
8223 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008224 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 }
8226 else
8227 {
Yue Maf49ba872013-08-19 12:04:25 -07008228 cfg80211_put_bss(
8229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8230 wiphy,
8231#endif
8232 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 }
8234
8235 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8236 }
8237
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008239
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308240 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008241}
8242
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008243void
8244hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8245{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308246 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008247 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008248} /****** end hddPrintMacAddr() ******/
8249
8250void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008251hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308253 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008254 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008255 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8256 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8257 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008258} /****** end hddPrintPmkId() ******/
8259
8260//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8261//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8262
8263//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8264//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8265
8266#define dump_bssid(bssid) \
8267 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008268 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8269 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008270 }
8271
8272#define dump_pmkid(pMac, pmkid) \
8273 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008274 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8275 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008276 }
8277
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008278#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008279/*
8280 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8281 * This function is used to notify the supplicant of a new PMKSA candidate.
8282 */
8283int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308284 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008285 int index, bool preauth )
8286{
Jeff Johnsone7245742012-09-05 17:12:55 -07008287#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008288 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008289 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008290
8291 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008292 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008293
8294 if( NULL == pRoamInfo )
8295 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008296 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008297 return -EINVAL;
8298 }
8299
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008300 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8301 {
8302 dump_bssid(pRoamInfo->bssid);
8303 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008304 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008305 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008306#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308307 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008308}
8309#endif //FEATURE_WLAN_LFR
8310
Yue Maef608272013-04-08 23:09:17 -07008311#ifdef FEATURE_WLAN_LFR_METRICS
8312/*
8313 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8314 * 802.11r/LFR metrics reporting function to report preauth initiation
8315 *
8316 */
8317#define MAX_LFR_METRICS_EVENT_LENGTH 100
8318VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8319 tCsrRoamInfo *pRoamInfo)
8320{
8321 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8322 union iwreq_data wrqu;
8323
8324 ENTER();
8325
8326 if (NULL == pAdapter)
8327 {
8328 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8329 return VOS_STATUS_E_FAILURE;
8330 }
8331
8332 /* create the event */
8333 memset(&wrqu, 0, sizeof(wrqu));
8334 memset(metrics_notification, 0, sizeof(metrics_notification));
8335
8336 wrqu.data.pointer = metrics_notification;
8337 wrqu.data.length = scnprintf(metrics_notification,
8338 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8339 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8340
8341 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8342
8343 EXIT();
8344
8345 return VOS_STATUS_SUCCESS;
8346}
8347
8348/*
8349 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8350 * 802.11r/LFR metrics reporting function to report preauth completion
8351 * or failure
8352 */
8353VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8354 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8355{
8356 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8357 union iwreq_data wrqu;
8358
8359 ENTER();
8360
8361 if (NULL == pAdapter)
8362 {
8363 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8364 return VOS_STATUS_E_FAILURE;
8365 }
8366
8367 /* create the event */
8368 memset(&wrqu, 0, sizeof(wrqu));
8369 memset(metrics_notification, 0, sizeof(metrics_notification));
8370
8371 scnprintf(metrics_notification, sizeof(metrics_notification),
8372 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8373 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8374
8375 if (1 == preauth_status)
8376 strncat(metrics_notification, " TRUE", 5);
8377 else
8378 strncat(metrics_notification, " FALSE", 6);
8379
8380 wrqu.data.pointer = metrics_notification;
8381 wrqu.data.length = strlen(metrics_notification);
8382
8383 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8384
8385 EXIT();
8386
8387 return VOS_STATUS_SUCCESS;
8388}
8389
8390/*
8391 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8392 * 802.11r/LFR metrics reporting function to report handover initiation
8393 *
8394 */
8395VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8396 tCsrRoamInfo *pRoamInfo)
8397{
8398 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8399 union iwreq_data wrqu;
8400
8401 ENTER();
8402
8403 if (NULL == pAdapter)
8404 {
8405 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8406 return VOS_STATUS_E_FAILURE;
8407 }
8408
8409 /* create the event */
8410 memset(&wrqu, 0, sizeof(wrqu));
8411 memset(metrics_notification, 0, sizeof(metrics_notification));
8412
8413 wrqu.data.pointer = metrics_notification;
8414 wrqu.data.length = scnprintf(metrics_notification,
8415 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8416 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8417
8418 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8419
8420 EXIT();
8421
8422 return VOS_STATUS_SUCCESS;
8423}
8424#endif
8425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426/*
8427 * FUNCTION: hdd_cfg80211_scan_done_callback
8428 * scanning callback function, called after finishing scan
8429 *
8430 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308431static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8433{
8434 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308435 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008437 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8438 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 struct cfg80211_scan_request *req = NULL;
8440 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308441 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308442 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443
8444 ENTER();
8445
8446 hddLog(VOS_TRACE_LEVEL_INFO,
8447 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008448 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 __func__, halHandle, pContext, (int) scanId, (int) status);
8450
Kiet Lamac06e2c2013-10-23 16:25:07 +05308451 pScanInfo->mScanPendingCounter = 0;
8452
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308454 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 &pScanInfo->scan_req_completion_event,
8456 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308457 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308459 hddLog(VOS_TRACE_LEVEL_ERROR,
8460 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008462 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 }
8464
Yue Maef608272013-04-08 23:09:17 -07008465 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 {
8467 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008468 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 }
8470
8471 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 {
8474 hddLog(VOS_TRACE_LEVEL_INFO,
8475 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008476 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 (int) scanId);
8478 }
8479
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308480 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 pAdapter);
8482
8483 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008485
8486
8487 /* If any client wait scan result through WEXT
8488 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008489 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 {
8491 /* The other scan request waiting for current scan finish
8492 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008493 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008495 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 }
8497 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008498 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 {
8500 struct net_device *dev = pAdapter->dev;
8501 union iwreq_data wrqu;
8502 int we_event;
8503 char *msg;
8504
8505 memset(&wrqu, '\0', sizeof(wrqu));
8506 we_event = SIOCGIWSCAN;
8507 msg = NULL;
8508 wireless_send_event(dev, we_event, &wrqu, msg);
8509 }
8510 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008511 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008512
8513 /* Get the Scan Req */
8514 req = pAdapter->request;
8515
8516 if (!req)
8517 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008518 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008519 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008520 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 }
8522
8523 /*
8524 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308525 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008526 req->n_ssids = 0;
8527 req->n_channels = 0;
8528 req->ie = 0;
8529
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008531 /* Scan is no longer pending */
8532 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008533
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008534 /*
8535 * cfg80211_scan_done informing NL80211 about completion
8536 * of scanning
8537 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308538 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8539 {
8540 aborted = true;
8541 }
8542 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008543 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008544
Jeff Johnsone7245742012-09-05 17:12:55 -07008545allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008546 /* release the wake lock at the end of the scan*/
8547 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008548
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008549 /* Acquire wakelock to handle the case where APP's tries to suspend
8550 * immediatly after the driver gets connect request(i.e after scan)
8551 * from supplicant, this result in app's is suspending and not able
8552 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308553 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008554
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008555#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308556 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8557 {
8558 wlan_hdd_tdls_scan_done_callback(pAdapter);
8559 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008560#endif
8561
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 EXIT();
8563 return 0;
8564}
8565
8566/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308567 * FUNCTION: hdd_isConnectionInProgress
8568 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008569 *
8570 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308571v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008572{
8573 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8574 hdd_station_ctx_t *pHddStaCtx = NULL;
8575 hdd_adapter_t *pAdapter = NULL;
8576 VOS_STATUS status = 0;
8577 v_U8_t staId = 0;
8578 v_U8_t *staMac = NULL;
8579
c_hpothu9b781ba2013-12-30 20:57:45 +05308580 if (TRUE == pHddCtx->btCoexModeSet)
8581 {
8582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308583 FL("BTCoex Mode operation in progress"));
8584 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308585 }
8586
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008587 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8588
8589 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8590 {
8591 pAdapter = pAdapterNode->pAdapter;
8592
8593 if( pAdapter )
8594 {
8595 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308596 "%s: Adapter with device mode %s (%d) exists",
8597 __func__, hdd_device_modetoString(pAdapter->device_mode),
8598 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308599 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8600 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8601 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8602 (eConnectionState_Connecting ==
8603 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8604 {
8605 hddLog(VOS_TRACE_LEVEL_ERROR,
8606 "%s: %p(%d) Connection is in progress", __func__,
8607 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8608 return VOS_TRUE;
8609 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008610 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308611 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8612 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008613 {
8614 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8615 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308616 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008617 {
8618 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8619 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008620 "%s: client " MAC_ADDRESS_STR
8621 " is in the middle of WPS/EAPOL exchange.", __func__,
8622 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308623 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008624 }
8625 }
8626 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8627 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8628 {
8629 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308631 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008632 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8633 {
8634 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8635
8636 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008637 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8638 "middle of WPS/EAPOL exchange.", __func__,
8639 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308640 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008641 }
8642 }
8643 }
8644 }
8645 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8646 pAdapterNode = pNext;
8647 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308648 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308649}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008650
8651/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308652 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008653 * this scan respond to scan trigger and update cfg80211 scan database
8654 * later, scan dump command can be used to recieve scan results
8655 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308656int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008657#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8658 struct net_device *dev,
8659#endif
8660 struct cfg80211_scan_request *request)
8661{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308662 hdd_adapter_t *pAdapter = NULL;
8663 hdd_context_t *pHddCtx = NULL;
8664 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308665 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 tCsrScanRequest scanRequest;
8667 tANI_U8 *channelList = NULL, i;
8668 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308669 int status;
8670 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008672
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8674 struct net_device *dev = NULL;
8675 if (NULL == request)
8676 {
8677 hddLog(VOS_TRACE_LEVEL_ERROR,
8678 "%s: scan req param null", __func__);
8679 return -EINVAL;
8680 }
8681 dev = request->wdev->netdev;
8682#endif
8683
8684 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8685 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8686 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8687
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 ENTER();
8689
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308690 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8691 __func__, hdd_device_modetoString(pAdapter->device_mode),
8692 pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308693 status = wlan_hdd_validate_context(pHddCtx);
8694
8695 if (0 != status)
8696 {
8697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8698 "%s: HDD context is not valid", __func__);
8699 return status;
8700 }
8701
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308702 if (NULL == pwextBuf)
8703 {
8704 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8705 __func__);
8706 return -EIO;
8707 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308708 cfg_param = pHddCtx->cfg_ini;
8709 pScanInfo = &pHddCtx->scan_info;
8710
Jeff Johnson295189b2012-06-20 16:38:30 -07008711#ifdef WLAN_BTAMP_FEATURE
8712 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008713 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008715 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 "%s: No scanning when AMP is on", __func__);
8717 return -EOPNOTSUPP;
8718 }
8719#endif
8720 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008721 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008723 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308724 "%s: Not scanning on device_mode = %s (%d)",
8725 __func__, hdd_device_modetoString(pAdapter->device_mode),
8726 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 return -EOPNOTSUPP;
8728 }
8729
8730 if (TRUE == pScanInfo->mScanPending)
8731 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308732 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8733 {
8734 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8735 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008736 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 }
8738
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308739 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008740 //Channel and action frame is pending
8741 //Otherwise Cancel Remain On Channel and allow Scan
8742 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008743 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008744 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308745 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008746 return -EBUSY;
8747 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008748#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008749 /* if tdls disagree scan right now, return immediately.
8750 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8751 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8752 */
8753 status = wlan_hdd_tdls_scan_callback (pAdapter,
8754 wiphy,
8755#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8756 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008757#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008758 request);
8759 if(status <= 0)
8760 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308761 if(!status)
8762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8763 "scan rejected %d", __func__, status);
8764 else
8765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8766 __func__, status);
8767
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008768 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008769 }
8770#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008771
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8773 {
8774 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008775 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308777 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8779 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308780 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 "%s: MAX TM Level Scan not allowed", __func__);
8782 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308783 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 }
8785 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8786
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008787 /* Check if scan is allowed at this point of time.
8788 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308789 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008790 {
8791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8792 return -EBUSY;
8793 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308794
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8796
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308797 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8798 (int)request->n_ssids);
8799
8800 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8801 * Becasue of this, driver is assuming that this is not wildcard scan and so
8802 * is not aging out the scan results.
8803 */
8804 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308806 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308808
8809 if ((request->ssids) && (0 < request->n_ssids))
8810 {
8811 tCsrSSIDInfo *SsidInfo;
8812 int j;
8813 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8814 /* Allocate num_ssid tCsrSSIDInfo structure */
8815 SsidInfo = scanRequest.SSIDs.SSIDList =
8816 ( tCsrSSIDInfo *)vos_mem_malloc(
8817 request->n_ssids*sizeof(tCsrSSIDInfo));
8818
8819 if(NULL == scanRequest.SSIDs.SSIDList)
8820 {
8821 hddLog(VOS_TRACE_LEVEL_ERROR,
8822 "%s: memory alloc failed SSIDInfo buffer", __func__);
8823 return -ENOMEM;
8824 }
8825
8826 /* copy all the ssid's and their length */
8827 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8828 {
8829 /* get the ssid length */
8830 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8831 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8832 SsidInfo->SSID.length);
8833 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8834 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8835 j, SsidInfo->SSID.ssId);
8836 }
8837 /* set the scan type to active */
8838 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8839 }
8840 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308842 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8843 TRACE_CODE_HDD_CFG80211_SCAN,
8844 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 /* set the scan type to active */
8846 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308848 else
8849 {
8850 /*Set the scan type to default type, in this case it is ACTIVE*/
8851 scanRequest.scanType = pScanInfo->scan_mode;
8852 }
8853 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8854 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008855
8856 /* set BSSType to default type */
8857 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8858
8859 /*TODO: scan the requested channels only*/
8860
8861 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308862 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308864 hddLog(VOS_TRACE_LEVEL_WARN,
8865 "No of Scan Channels exceeded limit: %d", request->n_channels);
8866 request->n_channels = MAX_CHANNEL;
8867 }
8868
8869 hddLog(VOS_TRACE_LEVEL_INFO,
8870 "No of Scan Channels: %d", request->n_channels);
8871
8872
8873 if( request->n_channels )
8874 {
8875 char chList [(request->n_channels*5)+1];
8876 int len;
8877 channelList = vos_mem_malloc( request->n_channels );
8878 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308879 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308880 hddLog(VOS_TRACE_LEVEL_ERROR,
8881 "%s: memory alloc failed channelList", __func__);
8882 status = -ENOMEM;
8883 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308884 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308885
8886 for( i = 0, len = 0; i < request->n_channels ; i++ )
8887 {
8888 channelList[i] = request->channels[i]->hw_value;
8889 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8890 }
8891
Nirav Shah20ac06f2013-12-12 18:14:06 +05308892 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308893 "Channel-List: %s ", chList);
8894 }
c_hpothu53512302014-04-15 18:49:53 +05308895
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308896 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8897 scanRequest.ChannelInfo.ChannelList = channelList;
8898
8899 /* set requestType to full scan */
8900 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8901
8902 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8903 * search (Flush on both full scan and social scan but not on single
8904 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8905 */
8906
8907 /* Supplicant does single channel scan after 8-way handshake
8908 * and in that case driver shoudnt flush scan results. If
8909 * driver flushes the scan results here and unfortunately if
8910 * the AP doesnt respond to our probe req then association
8911 * fails which is not desired
8912 */
8913
8914 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8915 {
8916 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8917 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8918 pAdapter->sessionId );
8919 }
8920
8921 if( request->ie_len )
8922 {
8923 /* save this for future association (join requires this) */
8924 /*TODO: Array needs to be converted to dynamic allocation,
8925 * as multiple ie.s can be sent in cfg80211_scan_request structure
8926 * CR 597966
8927 */
8928 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8929 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8930 pScanInfo->scanAddIE.length = request->ie_len;
8931
8932 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8933 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8934 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308936 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308938 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8939 memcpy( pwextBuf->roamProfile.addIEScan,
8940 request->ie, request->ie_len);
8941 }
8942 else
8943 {
8944 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8945 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 }
8947
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308948 }
8949 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8950 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8951
8952 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8953 request->ie_len);
8954 if (pP2pIe != NULL)
8955 {
8956#ifdef WLAN_FEATURE_P2P_DEBUG
8957 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8958 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8959 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308960 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308961 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8962 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8963 "Go nego completed to Connection is started");
8964 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8965 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308966 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308967 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8968 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308970 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8971 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8972 "Disconnected state to Connection is started");
8973 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8974 "for 4way Handshake");
8975 }
8976#endif
8977
8978 /* no_cck will be set during p2p find to disable 11b rates */
8979 if(TRUE == request->no_cck)
8980 {
8981 hddLog(VOS_TRACE_LEVEL_INFO,
8982 "%s: This is a P2P Search", __func__);
8983 scanRequest.p2pSearch = 1;
8984
8985 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308986 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308987 /* set requestType to P2P Discovery */
8988 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8989 }
8990
8991 /*
8992 Skip Dfs Channel in case of P2P Search
8993 if it is set in ini file
8994 */
8995 if(cfg_param->skipDfsChnlInP2pSearch)
8996 {
8997 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308998 }
8999 else
9000 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309001 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009003
Agarwal Ashish4f616132013-12-30 23:32:50 +05309004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 }
9006 }
9007
9008 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9009
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009010 /* acquire the wakelock to avoid the apps suspend during the scan. To
9011 * address the following issues.
9012 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9013 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9014 * for long time, this result in apps running at full power for long time.
9015 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9016 * be stuck in full power because of resume BMPS
9017 */
9018 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009019
Nirav Shah20ac06f2013-12-12 18:14:06 +05309020 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9021 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309022 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9023 scanRequest.requestType, scanRequest.scanType,
9024 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309025 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9026
Jeff Johnsone7245742012-09-05 17:12:55 -07009027 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 pAdapter->sessionId, &scanRequest, &scanId,
9029 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009030
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 if (eHAL_STATUS_SUCCESS != status)
9032 {
9033 hddLog(VOS_TRACE_LEVEL_ERROR,
9034 "%s: sme_ScanRequest returned error %d", __func__, status);
9035 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009036 if(eHAL_STATUS_RESOURCES == status)
9037 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9039 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009040 status = -EBUSY;
9041 } else {
9042 status = -EIO;
9043 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009044 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 goto free_mem;
9046 }
9047
9048 pScanInfo->mScanPending = TRUE;
9049 pAdapter->request = request;
9050 pScanInfo->scanId = scanId;
9051
9052 complete(&pScanInfo->scan_req_completion_event);
9053
9054free_mem:
9055 if( scanRequest.SSIDs.SSIDList )
9056 {
9057 vos_mem_free(scanRequest.SSIDs.SSIDList);
9058 }
9059
9060 if( channelList )
9061 vos_mem_free( channelList );
9062
9063 EXIT();
9064
9065 return status;
9066}
9067
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309068int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9070 struct net_device *dev,
9071#endif
9072 struct cfg80211_scan_request *request)
9073{
9074 int ret;
9075
9076 vos_ssr_protect(__func__);
9077 ret = __wlan_hdd_cfg80211_scan(wiphy,
9078#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9079 dev,
9080#endif
9081 request);
9082 vos_ssr_unprotect(__func__);
9083
9084 return ret;
9085}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009086
9087void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9088{
9089 v_U8_t iniDot11Mode =
9090 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9091 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9092
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309093 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9094 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009095 switch ( iniDot11Mode )
9096 {
9097 case eHDD_DOT11_MODE_AUTO:
9098 case eHDD_DOT11_MODE_11ac:
9099 case eHDD_DOT11_MODE_11ac_ONLY:
9100#ifdef WLAN_FEATURE_11AC
9101 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9102#else
9103 hddDot11Mode = eHDD_DOT11_MODE_11n;
9104#endif
9105 break;
9106 case eHDD_DOT11_MODE_11n:
9107 case eHDD_DOT11_MODE_11n_ONLY:
9108 hddDot11Mode = eHDD_DOT11_MODE_11n;
9109 break;
9110 default:
9111 hddDot11Mode = iniDot11Mode;
9112 break;
9113 }
9114 /* This call decides required channel bonding mode */
9115 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9116 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9117 operationChannel);
9118}
9119
Jeff Johnson295189b2012-06-20 16:38:30 -07009120/*
9121 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309122 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309124int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009125 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009126{
9127 int status = 0;
9128 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009129 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 v_U32_t roamId;
9131 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009132 eCsrAuthType RSNAuthType;
9133
9134 ENTER();
9135
9136 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009137 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9138
9139 status = wlan_hdd_validate_context(pHddCtx);
9140 if (status)
9141 {
9142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9143 "%s: HDD context is not valid!", __func__);
9144 return status;
9145 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309146
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9148 {
9149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9150 return -EINVAL;
9151 }
9152
9153 pRoamProfile = &pWextState->roamProfile;
9154
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309155 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009157 hdd_station_ctx_t *pHddStaCtx;
9158 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009159
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309160 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9162 {
9163 /*QoS not enabled in cfg file*/
9164 pRoamProfile->uapsd_mask = 0;
9165 }
9166 else
9167 {
9168 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309169 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9171 }
9172
9173 pRoamProfile->SSIDs.numOfSSIDs = 1;
9174 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9175 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309176 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9178 ssid, ssid_len);
9179
9180 if (bssid)
9181 {
9182 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9183 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9184 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309185 /* Save BSSID in seperate variable as well, as RoamProfile
9186 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 case of join failure we should send valid BSSID to supplicant
9188 */
9189 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9190 WNI_CFG_BSSID_LEN);
9191 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009192 else
9193 {
9194 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309197 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9198 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9200 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309201 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 /*set gen ie*/
9203 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9204 /*set auth*/
9205 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009207#ifdef FEATURE_WLAN_WAPI
9208 if (pAdapter->wapi_info.nWapiMode)
9209 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009210 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 switch (pAdapter->wapi_info.wapiAuthMode)
9212 {
9213 case WAPI_AUTH_MODE_PSK:
9214 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009215 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 pAdapter->wapi_info.wapiAuthMode);
9217 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9218 break;
9219 }
9220 case WAPI_AUTH_MODE_CERT:
9221 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009222 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 pAdapter->wapi_info.wapiAuthMode);
9224 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9225 break;
9226 }
9227 } // End of switch
9228 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9229 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9230 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009231 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 pRoamProfile->AuthType.numEntries = 1;
9233 pRoamProfile->EncryptionType.numEntries = 1;
9234 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9235 pRoamProfile->mcEncryptionType.numEntries = 1;
9236 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9237 }
9238 }
9239#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309240#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309241 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309242 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9243 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9244 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309245 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9246 sizeof (tSirGtkOffloadParams));
9247 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309248 }
9249#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 pRoamProfile->csrPersona = pAdapter->device_mode;
9251
Jeff Johnson32d95a32012-09-10 13:15:23 -07009252 if( operatingChannel )
9253 {
9254 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9255 pRoamProfile->ChannelInfo.numOfChannels = 1;
9256 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009257 else
9258 {
9259 pRoamProfile->ChannelInfo.ChannelList = NULL;
9260 pRoamProfile->ChannelInfo.numOfChannels = 0;
9261 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009262 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9263 {
9264 hdd_select_cbmode(pAdapter,operatingChannel);
9265 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309266
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009267 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9268 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009270 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009271 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9272 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309273 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9274 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309275 {
9276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9277 "%s: Set HDD connState to eConnectionState_Connecting",
9278 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009279 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9280 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309281 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309282 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 pAdapter->sessionId, pRoamProfile, &roamId);
9284
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309285 if ((eHAL_STATUS_SUCCESS != status) &&
9286 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9287 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309288
9289 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9291 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9292 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309293 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009294 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309295 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009296
9297 pRoamProfile->ChannelInfo.ChannelList = NULL;
9298 pRoamProfile->ChannelInfo.numOfChannels = 0;
9299
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 }
9301 else
9302 {
9303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9304 return -EINVAL;
9305 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009306 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 return status;
9308}
9309
9310/*
9311 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9312 * This function is used to set the authentication type (OPEN/SHARED).
9313 *
9314 */
9315static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9316 enum nl80211_auth_type auth_type)
9317{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9320
9321 ENTER();
9322
9323 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309324 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309327 hddLog(VOS_TRACE_LEVEL_INFO,
9328 "%s: set authentication type to AUTOSWITCH", __func__);
9329 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9330 break;
9331
9332 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009333#ifdef WLAN_FEATURE_VOWIFI_11R
9334 case NL80211_AUTHTYPE_FT:
9335#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309336 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 "%s: set authentication type to OPEN", __func__);
9338 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9339 break;
9340
9341 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309342 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 "%s: set authentication type to SHARED", __func__);
9344 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9345 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009346#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309348 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 "%s: set authentication type to CCKM WPA", __func__);
9350 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9351 break;
9352#endif
9353
9354
9355 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309356 hddLog(VOS_TRACE_LEVEL_ERROR,
9357 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 auth_type);
9359 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9360 return -EINVAL;
9361 }
9362
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 pHddStaCtx->conn_info.authType;
9365 return 0;
9366}
9367
9368/*
9369 * FUNCTION: wlan_hdd_set_akm_suite
9370 * This function is used to set the key mgmt type(PSK/8021x).
9371 *
9372 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309373static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 u32 key_mgmt
9375 )
9376{
9377 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9378 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 /*set key mgmt type*/
9381 switch(key_mgmt)
9382 {
9383 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309384#ifdef WLAN_FEATURE_VOWIFI_11R
9385 case WLAN_AKM_SUITE_FT_PSK:
9386#endif
9387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 __func__);
9389 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9390 break;
9391
9392 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309393#ifdef WLAN_FEATURE_VOWIFI_11R
9394 case WLAN_AKM_SUITE_FT_8021X:
9395#endif
9396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 __func__);
9398 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9399 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009400#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009401#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9402#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9403 case WLAN_AKM_SUITE_CCKM:
9404 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9405 __func__);
9406 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9407 break;
9408#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009409#ifndef WLAN_AKM_SUITE_OSEN
9410#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9411 case WLAN_AKM_SUITE_OSEN:
9412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9413 __func__);
9414 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9415 break;
9416#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009417
9418 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 __func__, key_mgmt);
9421 return -EINVAL;
9422
9423 }
9424 return 0;
9425}
9426
9427/*
9428 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309429 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 * (NONE/WEP40/WEP104/TKIP/CCMP).
9431 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309432static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9433 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 bool ucast
9435 )
9436{
9437 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309438 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9440
9441 ENTER();
9442
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309443 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 __func__, cipher);
9447 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9448 }
9449 else
9450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309451
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 {
9455 case IW_AUTH_CIPHER_NONE:
9456 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9457 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309458
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309460 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309464 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 case WLAN_CIPHER_SUITE_TKIP:
9468 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9469 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309470
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 case WLAN_CIPHER_SUITE_CCMP:
9472 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9473 break;
9474#ifdef FEATURE_WLAN_WAPI
9475 case WLAN_CIPHER_SUITE_SMS4:
9476 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9477 break;
9478#endif
9479
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009480#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 case WLAN_CIPHER_SUITE_KRK:
9482 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9483 break;
9484#endif
9485 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 __func__, cipher);
9488 return -EOPNOTSUPP;
9489 }
9490 }
9491
9492 if (ucast)
9493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 __func__, encryptionType);
9496 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9497 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309498 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 encryptionType;
9500 }
9501 else
9502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 __func__, encryptionType);
9505 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9506 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9507 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9508 }
9509
9510 return 0;
9511}
9512
9513
9514/*
9515 * FUNCTION: wlan_hdd_cfg80211_set_ie
9516 * This function is used to parse WPA/RSN IE's.
9517 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9519 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 size_t ie_len
9521 )
9522{
9523 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9524 u8 *genie = ie;
9525 v_U16_t remLen = ie_len;
9526#ifdef FEATURE_WLAN_WAPI
9527 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9528 u16 *tmp;
9529 v_U16_t akmsuiteCount;
9530 int *akmlist;
9531#endif
9532 ENTER();
9533
9534 /* clear previous assocAddIE */
9535 pWextState->assocAddIE.length = 0;
9536 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009537 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009538
9539 while (remLen >= 2)
9540 {
9541 v_U16_t eLen = 0;
9542 v_U8_t elementId;
9543 elementId = *genie++;
9544 eLen = *genie++;
9545 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546
Arif Hussain6d2a3322013-11-17 19:50:10 -08009547 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309549
9550 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009553 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 -07009554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 "%s: Invalid WPA IE", __func__);
9557 return -EINVAL;
9558 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309559 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 {
9561 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309562 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309564
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9566 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009567 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9568 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 VOS_ASSERT(0);
9570 return -ENOMEM;
9571 }
9572 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9573 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9574 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309575
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9577 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9578 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9579 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9581 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9583 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9584 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9585 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9586 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9587 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309589 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 {
9591 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309594
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9596 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009597 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9598 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 VOS_ASSERT(0);
9600 return -ENOMEM;
9601 }
9602 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9603 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9604 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309605
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9607 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9608 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009609#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9611 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 /*Consider WFD IE, only for P2P Client */
9613 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9614 {
9615 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309616 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9620 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009621 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9622 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 VOS_ASSERT(0);
9624 return -ENOMEM;
9625 }
9626 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9627 // WPS IE + P2P IE + WFD IE
9628 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9629 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9632 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9633 }
9634#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009635 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009637 HS20_OUI_TYPE_SIZE)) )
9638 {
9639 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309640 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009641 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009642
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009643 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9644 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009645 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9646 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009647 VOS_ASSERT(0);
9648 return -ENOMEM;
9649 }
9650 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9651 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009652
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009653 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9654 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9655 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009656 /* Appending OSEN Information Element in Assiciation Request */
9657 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9658 OSEN_OUI_TYPE_SIZE)) )
9659 {
9660 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9661 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9662 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009663
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009664 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9665 {
9666 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9667 "Need bigger buffer space");
9668 VOS_ASSERT(0);
9669 return -ENOMEM;
9670 }
9671 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9672 pWextState->assocAddIE.length += eLen + 2;
9673
9674 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9675 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9676 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9677 }
9678
9679 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009680 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9681
9682 /* populating as ADDIE in beacon frames */
9683 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9684 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9685 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9686 {
9687 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9688 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9689 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9690 {
9691 hddLog(LOGE,
9692 "Coldn't pass "
9693 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9694 }
9695 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9696 else
9697 hddLog(LOGE,
9698 "Could not pass on "
9699 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9700
9701 /* IBSS mode doesn't contain params->proberesp_ies still
9702 beaconIE's need to be populated in probe response frames */
9703 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9704 {
9705 u16 rem_probe_resp_ie_len = eLen + 2;
9706 u8 probe_rsp_ie_len[3] = {0};
9707 u8 counter = 0;
9708
9709 /* Check Probe Resp Length if it is greater then 255 then
9710 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9711 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9712 not able Store More then 255 bytes into One Variable */
9713
9714 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9715 {
9716 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9717 {
9718 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9719 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9720 }
9721 else
9722 {
9723 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9724 rem_probe_resp_ie_len = 0;
9725 }
9726 }
9727
9728 rem_probe_resp_ie_len = 0;
9729
9730 if (probe_rsp_ie_len[0] > 0)
9731 {
9732 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9733 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9734 (tANI_U8*)(genie - 2),
9735 probe_rsp_ie_len[0], NULL,
9736 eANI_BOOLEAN_FALSE)
9737 == eHAL_STATUS_FAILURE)
9738 {
9739 hddLog(LOGE,
9740 "Could not pass"
9741 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9742 }
9743 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9744 }
9745
9746 if (probe_rsp_ie_len[1] > 0)
9747 {
9748 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9749 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9750 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9751 probe_rsp_ie_len[1], NULL,
9752 eANI_BOOLEAN_FALSE)
9753 == eHAL_STATUS_FAILURE)
9754 {
9755 hddLog(LOGE,
9756 "Could not pass"
9757 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9758 }
9759 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9760 }
9761
9762 if (probe_rsp_ie_len[2] > 0)
9763 {
9764 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9765 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9766 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9767 probe_rsp_ie_len[2], NULL,
9768 eANI_BOOLEAN_FALSE)
9769 == eHAL_STATUS_FAILURE)
9770 {
9771 hddLog(LOGE,
9772 "Could not pass"
9773 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9774 }
9775 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9776 }
9777
9778 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9779 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9780 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9781 {
9782 hddLog(LOGE,
9783 "Could not pass"
9784 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9785 }
9786 }
9787 else
9788 {
9789 // Reset WNI_CFG_PROBE_RSP Flags
9790 wlan_hdd_reset_prob_rspies(pAdapter);
9791
9792 hddLog(VOS_TRACE_LEVEL_INFO,
9793 "%s: No Probe Response IE received in set beacon",
9794 __func__);
9795 }
9796 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009797 break;
9798 case DOT11F_EID_RSN:
9799 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9800 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9801 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9802 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9803 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9804 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009805 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9806 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309807 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009808 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309809 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009810 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309811
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009812 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9813 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009814 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9815 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009816 VOS_ASSERT(0);
9817 return -ENOMEM;
9818 }
9819 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9820 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309821
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009822 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9823 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9824 break;
9825 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009826#ifdef FEATURE_WLAN_WAPI
9827 case WLAN_EID_WAPI:
9828 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009829 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 pAdapter->wapi_info.nWapiMode);
9831 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309832 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 akmsuiteCount = WPA_GET_LE16(tmp);
9834 tmp = tmp + 1;
9835 akmlist = (int *)(tmp);
9836 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9837 {
9838 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9839 }
9840 else
9841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009842 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 VOS_ASSERT(0);
9844 return -EINVAL;
9845 }
9846
9847 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9848 {
9849 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009850 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009856 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9858 }
9859 break;
9860#endif
9861 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309862 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009864 /* when Unknown IE is received we should break and continue
9865 * to the next IE in the buffer instead we were returning
9866 * so changing this to break */
9867 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 }
9869 genie += eLen;
9870 remLen -= eLen;
9871 }
9872 EXIT();
9873 return 0;
9874}
9875
9876/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309877 * FUNCTION: hdd_isWPAIEPresent
9878 * Parse the received IE to find the WPA IE
9879 *
9880 */
9881static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9882{
9883 v_U8_t eLen = 0;
9884 v_U16_t remLen = ie_len;
9885 v_U8_t elementId = 0;
9886
9887 while (remLen >= 2)
9888 {
9889 elementId = *ie++;
9890 eLen = *ie++;
9891 remLen -= 2;
9892 if (eLen > remLen)
9893 {
9894 hddLog(VOS_TRACE_LEVEL_ERROR,
9895 "%s: IE length is wrong %d", __func__, eLen);
9896 return FALSE;
9897 }
9898 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9899 {
9900 /* OUI - 0x00 0X50 0XF2
9901 WPA Information Element - 0x01
9902 WPA version - 0x01*/
9903 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9904 return TRUE;
9905 }
9906 ie += eLen;
9907 remLen -= eLen;
9908 }
9909 return FALSE;
9910}
9911
9912/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309914 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 * parameters during connect operation.
9916 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309917int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 struct cfg80211_connect_params *req
9919 )
9920{
9921 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309922 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 ENTER();
9924
9925 /*set wpa version*/
9926 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9927
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309930 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 {
9932 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9933 }
9934 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9935 {
9936 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9937 }
9938 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309939
9940 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 pWextState->wpaVersion);
9942
9943 /*set authentication type*/
9944 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9945
9946 if (0 > status)
9947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309948 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 "%s: failed to set authentication type ", __func__);
9950 return status;
9951 }
9952
9953 /*set key mgmt type*/
9954 if (req->crypto.n_akm_suites)
9955 {
9956 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9957 if (0 > status)
9958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 __func__);
9961 return status;
9962 }
9963 }
9964
9965 /*set pairwise cipher type*/
9966 if (req->crypto.n_ciphers_pairwise)
9967 {
9968 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9969 req->crypto.ciphers_pairwise[0], true);
9970 if (0 > status)
9971 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309972 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 "%s: failed to set unicast cipher type", __func__);
9974 return status;
9975 }
9976 }
9977 else
9978 {
9979 /*Reset previous cipher suite to none*/
9980 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9981 if (0 > status)
9982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309983 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 "%s: failed to set unicast cipher type", __func__);
9985 return status;
9986 }
9987 }
9988
9989 /*set group cipher type*/
9990 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9991 false);
9992
9993 if (0 > status)
9994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 __func__);
9997 return status;
9998 }
9999
Chet Lanctot186b5732013-03-18 10:26:30 -070010000#ifdef WLAN_FEATURE_11W
10001 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10002#endif
10003
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10005 if (req->ie_len)
10006 {
10007 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10008 if ( 0 > status)
10009 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 __func__);
10012 return status;
10013 }
10014 }
10015
10016 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010017 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 {
10019 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10020 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10021 )
10022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 __func__);
10028 return -EOPNOTSUPP;
10029 }
10030 else
10031 {
10032 u8 key_len = req->key_len;
10033 u8 key_idx = req->key_idx;
10034
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 && (CSR_MAX_NUM_KEY > key_idx)
10037 )
10038 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010039 hddLog(VOS_TRACE_LEVEL_INFO,
10040 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 __func__, key_idx, key_len);
10042 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 (u8)key_len;
10047 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10048 }
10049 }
10050 }
10051 }
10052
10053 return status;
10054}
10055
10056/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010057 * FUNCTION: wlan_hdd_try_disconnect
10058 * This function is used to disconnect from previous
10059 * connection
10060 */
10061static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10062{
10063 long ret = 0;
10064 hdd_station_ctx_t *pHddStaCtx;
10065 eMib_dot11DesiredBssType connectedBssType;
10066
10067 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10068
10069 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10070
10071 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10072 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10073 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10074 {
10075 /* Issue disconnect to CSR */
10076 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10077 if( eHAL_STATUS_SUCCESS ==
10078 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10079 pAdapter->sessionId,
10080 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10081 {
10082 ret = wait_for_completion_interruptible_timeout(
10083 &pAdapter->disconnect_comp_var,
10084 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10085 if (0 >= ret)
10086 {
10087 hddLog(LOGE, FL("Failed to receive disconnect event"));
10088 return -EALREADY;
10089 }
10090 }
10091 }
10092 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10093 {
10094 ret = wait_for_completion_interruptible_timeout(
10095 &pAdapter->disconnect_comp_var,
10096 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10097 if (0 >= ret)
10098 {
10099 hddLog(LOGE, FL("Failed to receive disconnect event"));
10100 return -EALREADY;
10101 }
10102 }
10103
10104 return 0;
10105}
10106
10107/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010108 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010109 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 * parameters during connect operation.
10111 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010112static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 struct net_device *ndev,
10114 struct cfg80211_connect_params *req
10115 )
10116{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010117 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushik10728722014-05-14 16:20:25 +053010120 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010121
10122 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010123 if (NULL == pAdapter)
10124 {
10125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10126 "%s: HDD adapter context is Null", __func__);
10127 return -ENODEV;
10128 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010129 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10130 TRACE_CODE_HDD_CFG80211_CONNECT,
10131 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010132 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010133 "%s: device_mode = %s (%d)", __func__,
10134 hdd_device_modetoString(pAdapter->device_mode),
10135 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010136
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010137 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010138 if (!pHddCtx)
10139 {
10140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10141 "%s: HDD context is null", __func__);
10142 return VOS_STATUS_E_FAILURE;
10143 }
10144
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010145 status = wlan_hdd_validate_context(pHddCtx);
10146
10147 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010148 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10150 "%s: HDD context is not valid", __func__);
10151 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 }
10153
10154#ifdef WLAN_BTAMP_FEATURE
10155 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010158 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010160 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 }
10162#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010163
10164 //If Device Mode is Station Concurrent Sessions Exit BMps
10165 //P2P Mode will be taken care in Open/close adapter
10166 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10167 (vos_concurrent_sessions_running()))
10168 {
10169 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10170 }
10171
10172 /*Try disconnecting if already in connected state*/
10173 status = wlan_hdd_try_disconnect(pAdapter);
10174 if ( 0 > status)
10175 {
10176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10177 " connection"));
10178 return -EALREADY;
10179 }
10180
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010182 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010183
10184 if ( 0 > status)
10185 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 __func__);
10188 return status;
10189 }
10190
Mohit Khanna765234a2012-09-11 15:08:35 -070010191 if ( req->channel )
10192 {
10193 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10194 req->ssid_len, req->bssid,
10195 req->channel->hw_value);
10196 }
10197 else
10198 {
10199 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010200 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010201 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010202
10203 if (0 > status)
10204 {
10205 //ReEnable BMPS if disabled
10206 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10207 (NULL != pHddCtx))
10208 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010209 if (pHddCtx->hdd_wlan_suspended)
10210 {
10211 hdd_set_pwrparams(pHddCtx);
10212 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 //ReEnable Bmps and Imps back
10214 hdd_enable_bmps_imps(pHddCtx);
10215 }
10216
10217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10218 return status;
10219 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010220 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 EXIT();
10222 return status;
10223}
10224
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010225static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10226 struct net_device *ndev,
10227 struct cfg80211_connect_params *req)
10228{
10229 int ret;
10230 vos_ssr_protect(__func__);
10231 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10232 vos_ssr_unprotect(__func__);
10233
10234 return ret;
10235}
Jeff Johnson295189b2012-06-20 16:38:30 -070010236
10237/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010238 * FUNCTION: wlan_hdd_disconnect
10239 * This function is used to issue a disconnect request to SME
10240 */
10241int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10242{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010243 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010244 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010245 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010246 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010247
10248 status = wlan_hdd_validate_context(pHddCtx);
10249
10250 if (0 != status)
10251 {
10252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10253 "%s: HDD context is not valid", __func__);
10254 return status;
10255 }
10256
10257 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10259 "%s: Set HDD connState to eConnectionState_Disconnecting",
10260 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010261 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010262 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010263
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010264 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010265
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010266 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10267 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010268 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10269 {
10270 hddLog(VOS_TRACE_LEVEL_INFO,
10271 FL("status = %d, already disconnected"),
10272 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010273
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010274 }
10275 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010276 {
10277 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010278 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010279 __func__, (int)status );
10280 return -EINVAL;
10281 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010282 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010283 &pAdapter->disconnect_comp_var,
10284 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010285 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010286 {
10287 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010288 "%s: Failed to disconnect, timed out", __func__);
10289 return -ETIMEDOUT;
10290 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010291 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010292 {
10293 hddLog(VOS_TRACE_LEVEL_ERROR,
10294 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010295 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010296 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10298 FL("Set HDD connState to eConnectionState_NotConnected"));
10299 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10300
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010301 /*stop tx queues*/
10302 netif_tx_disable(pAdapter->dev);
10303 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010304 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010305}
10306
10307
10308/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010309 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 * This function is used to issue a disconnect request to SME
10311 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010312static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 struct net_device *dev,
10314 u16 reason
10315 )
10316{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +053010318 tCsrRoamProfile *pRoamProfile = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010319 int status;
Sushant Kaushik10728722014-05-14 16:20:25 +053010320 hdd_station_ctx_t *pHddStaCtx = NULL;
10321 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010322#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010323 tANI_U8 staIdx;
10324#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010327 if (NULL == pAdapter)
10328 {
10329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10330 "%s: HDD adapter context is Null", __func__);
10331 return -ENODEV;
10332 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010333 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10334 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10335 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10337 __func__, hdd_device_modetoString(pAdapter->device_mode),
10338 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010339
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10341 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010342
Sushant Kaushik10728722014-05-14 16:20:25 +053010343 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
10344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10345 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010346 status = wlan_hdd_validate_context(pHddCtx);
10347
10348 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010349 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10351 "%s: HDD context is not valid", __func__);
10352 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010354
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 if (NULL != pRoamProfile)
10356 {
10357 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010358 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10359 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010361 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010363 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 switch(reason)
10365 {
10366 case WLAN_REASON_MIC_FAILURE:
10367 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10368 break;
10369
10370 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10371 case WLAN_REASON_DISASSOC_AP_BUSY:
10372 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10373 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10374 break;
10375
10376 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10377 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010378 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10380 break;
10381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 default:
10383 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10384 break;
10385 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010386 pScanInfo = &pHddCtx->scan_info;
10387 if (pScanInfo->mScanPending)
10388 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010389 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010390 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010391 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10392 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010393 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010394
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010395#ifdef FEATURE_WLAN_TDLS
10396 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010397 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010398 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010399 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10400 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010401 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010402 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010403 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010404 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010405 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010406 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010407 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010408 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010409 pAdapter->sessionId,
10410 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010411 }
10412 }
10413#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010414 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010415 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10416 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 {
10418 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010419 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 __func__, (int)status );
10421 return -EINVAL;
10422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010424 else
10425 {
10426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10427 "called while in %d state", __func__,
10428 pHddStaCtx->conn_info.connState);
10429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 }
10431 else
10432 {
10433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10434 }
10435
10436 return status;
10437}
10438
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010439static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10440 struct net_device *dev,
10441 u16 reason
10442 )
10443{
10444 int ret;
10445 vos_ssr_protect(__func__);
10446 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10447 vos_ssr_unprotect(__func__);
10448
10449 return ret;
10450}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010451
Jeff Johnson295189b2012-06-20 16:38:30 -070010452/*
10453 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010454 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 * settings in IBSS mode.
10456 */
10457static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 struct cfg80211_ibss_params *params
10460 )
10461{
10462 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010463 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10465 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010466
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 ENTER();
10468
10469 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010470 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010471
10472 if (params->ie_len && ( NULL != params->ie) )
10473 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010474 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10475 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 {
10477 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10478 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10479 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010480 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010482 tDot11fIEWPA dot11WPAIE;
10483 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010484 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010485
Wilson Yang00256342013-10-10 23:13:38 -070010486 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010487 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10488 params->ie_len, DOT11F_EID_WPA);
10489 if ( NULL != ie )
10490 {
10491 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10492 // Unpack the WPA IE
10493 //Skip past the EID byte and length byte - and four byte WiFi OUI
10494 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10495 &ie[2+4],
10496 ie[1] - 4,
10497 &dot11WPAIE);
10498 /*Extract the multicast cipher, the encType for unicast
10499 cipher for wpa-none is none*/
10500 encryptionType =
10501 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10502 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010503 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010504
Jeff Johnson295189b2012-06-20 16:38:30 -070010505 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10506
10507 if (0 > status)
10508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 __func__);
10511 return status;
10512 }
10513 }
10514
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010515 pWextState->roamProfile.AuthType.authType[0] =
10516 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10518
10519 if (params->privacy)
10520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010521 /* Security enabled IBSS, At this time there is no information available
10522 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010524 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010526 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 *enable privacy bit in beacons */
10528
10529 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10530 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010531 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10532 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10534 pWextState->roamProfile.EncryptionType.numEntries = 1;
10535 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 return status;
10537}
10538
10539/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010540 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010541 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010543static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 struct net_device *dev,
10545 struct cfg80211_ibss_params *params
10546 )
10547{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010549 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10550 tCsrRoamProfile *pRoamProfile;
10551 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010552 bool alloc_bssid = VOS_FALSE;
Sushant Kaushik10728722014-05-14 16:20:25 +053010553 hdd_station_ctx_t *pHddStaCtx = NULL;
10554 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010555
10556 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010557 if (NULL == pAdapter)
10558 {
10559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10560 "%s: HDD adapter context is Null", __func__);
10561 return -ENODEV;
10562 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10564 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10565 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010566 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010567 "%s: device_mode = %s (%d)", __func__,
10568 hdd_device_modetoString(pAdapter->device_mode),
10569 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010570
Sushant Kaushik10728722014-05-14 16:20:25 +053010571 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10572 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010573 status = wlan_hdd_validate_context(pHddCtx);
10574
10575 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010576 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10578 "%s: HDD context is not valid", __func__);
10579 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 }
10581
10582 if (NULL == pWextState)
10583 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010584 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 __func__);
10586 return -EIO;
10587 }
10588
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010589 /*Try disconnecting if already in connected state*/
10590 status = wlan_hdd_try_disconnect(pAdapter);
10591 if ( 0 > status)
10592 {
10593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10594 " IBSS connection"));
10595 return -EALREADY;
10596 }
10597
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 pRoamProfile = &pWextState->roamProfile;
10599
10600 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10601 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010602 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010603 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 return -EINVAL;
10605 }
10606
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010607 /* BSSID is provided by upper layers hence no need to AUTO generate */
10608 if (NULL != params->bssid) {
10609 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10610 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10611 hddLog (VOS_TRACE_LEVEL_ERROR,
10612 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10613 return -EIO;
10614 }
10615 }
krunal sonie9002db2013-11-25 14:24:17 -080010616 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10617 {
10618 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10619 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10620 {
10621 hddLog (VOS_TRACE_LEVEL_ERROR,
10622 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10623 return -EIO;
10624 }
10625 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10626 if (!params->bssid)
10627 {
10628 hddLog (VOS_TRACE_LEVEL_ERROR,
10629 "%s:Failed memory allocation", __func__);
10630 return -EIO;
10631 }
10632 vos_mem_copy((v_U8_t *)params->bssid,
10633 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10634 VOS_MAC_ADDR_SIZE);
10635 alloc_bssid = VOS_TRUE;
10636 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010637
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010639 if (NULL !=
10640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10641 params->chandef.chan)
10642#else
10643 params->channel)
10644#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010645 {
10646 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010647 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10648 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10649 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10650 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010651
10652 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010653 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010654 ieee80211_frequency_to_channel(
10655#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10656 params->chandef.chan->center_freq);
10657#else
10658 params->channel->center_freq);
10659#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010660
10661 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10662 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10665 __func__);
10666 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010667 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010668
10669 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010670 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010671 if (channelNum == validChan[indx])
10672 {
10673 break;
10674 }
10675 }
10676 if (indx >= numChans)
10677 {
10678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010679 __func__, channelNum);
10680 return -EINVAL;
10681 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010682 /* Set the Operational Channel */
10683 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10684 channelNum);
10685 pRoamProfile->ChannelInfo.numOfChannels = 1;
10686 pHddStaCtx->conn_info.operationChannel = channelNum;
10687 pRoamProfile->ChannelInfo.ChannelList =
10688 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 }
10690
10691 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010692 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 if (status < 0)
10694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 __func__);
10697 return status;
10698 }
10699
10700 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010701 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010702 params->ssid_len, params->bssid,
10703 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010704
10705 if (0 > status)
10706 {
10707 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10708 return status;
10709 }
10710
krunal sonie9002db2013-11-25 14:24:17 -080010711 if (NULL != params->bssid &&
10712 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10713 alloc_bssid == VOS_TRUE)
10714 {
10715 vos_mem_free(params->bssid);
10716 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010717 return 0;
10718}
10719
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010720static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10721 struct net_device *dev,
10722 struct cfg80211_ibss_params *params
10723 )
10724{
10725 int ret = 0;
10726
10727 vos_ssr_protect(__func__);
10728 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10729 vos_ssr_unprotect(__func__);
10730
10731 return ret;
10732}
10733
Jeff Johnson295189b2012-06-20 16:38:30 -070010734/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010735 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010736 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010738static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 struct net_device *dev
10740 )
10741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Sushant Kaushik10728722014-05-14 16:20:25 +053010743 hdd_wext_state_t *pWextState = NULL;
10744 tCsrRoamProfile *pRoamProfile = NULL;
10745 hdd_context_t *pHddCtx = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010746 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010747
10748 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053010749 if (NULL == pAdapter)
10750 {
10751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10752 "%s: HDD adapter context is Null", __func__);
10753 return -ENODEV;
10754 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10756 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10757 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Sushant Kaushik10728722014-05-14 16:20:25 +053010758 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010760 status = wlan_hdd_validate_context(pHddCtx);
10761
10762 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010763 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10765 "%s: HDD context is not valid", __func__);
10766 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010767 }
10768
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010769 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10770 hdd_device_modetoString(pAdapter->device_mode),
10771 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 if (NULL == pWextState)
10773 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010774 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 __func__);
10776 return -EIO;
10777 }
10778
10779 pRoamProfile = &pWextState->roamProfile;
10780
10781 /* Issue disconnect only if interface type is set to IBSS */
10782 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010784 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 __func__);
10786 return -EINVAL;
10787 }
10788
10789 /* Issue Disconnect request */
10790 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10791 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10792 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10793
10794 return 0;
10795}
10796
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010797static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10798 struct net_device *dev
10799 )
10800{
10801 int ret = 0;
10802
10803 vos_ssr_protect(__func__);
10804 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10805 vos_ssr_unprotect(__func__);
10806
10807 return ret;
10808}
10809
Jeff Johnson295189b2012-06-20 16:38:30 -070010810/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010811 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 * This function is used to set the phy parameters
10813 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10814 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010815static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 u32 changed)
10817{
10818 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10819 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010820 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010821
10822 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010823 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10824 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10825 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010826 status = wlan_hdd_validate_context(pHddCtx);
10827
10828 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010829 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10831 "%s: HDD context is not valid", __func__);
10832 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010833 }
10834
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10836 {
10837 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10838 WNI_CFG_RTS_THRESHOLD_STAMAX :
10839 wiphy->rts_threshold;
10840
10841 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010842 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010844 hddLog(VOS_TRACE_LEVEL_ERROR,
10845 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010846 __func__, rts_threshold);
10847 return -EINVAL;
10848 }
10849
10850 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10851 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010852 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010854 hddLog(VOS_TRACE_LEVEL_ERROR,
10855 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 __func__, rts_threshold);
10857 return -EIO;
10858 }
10859
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010860 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 rts_threshold);
10862 }
10863
10864 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10865 {
10866 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10867 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10868 wiphy->frag_threshold;
10869
10870 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010871 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873 hddLog(VOS_TRACE_LEVEL_ERROR,
10874 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 frag_threshold);
10876 return -EINVAL;
10877 }
10878
10879 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10880 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010881 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010883 hddLog(VOS_TRACE_LEVEL_ERROR,
10884 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 __func__, frag_threshold);
10886 return -EIO;
10887 }
10888
10889 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10890 frag_threshold);
10891 }
10892
10893 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10894 || (changed & WIPHY_PARAM_RETRY_LONG))
10895 {
10896 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10897 wiphy->retry_short :
10898 wiphy->retry_long;
10899
10900 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10901 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 __func__, retry_value);
10905 return -EINVAL;
10906 }
10907
10908 if (changed & WIPHY_PARAM_RETRY_SHORT)
10909 {
10910 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10911 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010912 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010914 hddLog(VOS_TRACE_LEVEL_ERROR,
10915 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 __func__, retry_value);
10917 return -EIO;
10918 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010919 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 __func__, retry_value);
10921 }
10922 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10923 {
10924 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10925 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010926 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010928 hddLog(VOS_TRACE_LEVEL_ERROR,
10929 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010930 __func__, retry_value);
10931 return -EIO;
10932 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010934 __func__, retry_value);
10935 }
10936 }
10937
10938 return 0;
10939}
10940
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010941static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10942 u32 changed)
10943{
10944 int ret;
10945
10946 vos_ssr_protect(__func__);
10947 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10948 vos_ssr_unprotect(__func__);
10949
10950 return ret;
10951}
10952
Jeff Johnson295189b2012-06-20 16:38:30 -070010953/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010954 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 * This function is used to set the txpower
10956 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010957static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010958#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10959 struct wireless_dev *wdev,
10960#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010961#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010962 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010963#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010964 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010965#endif
10966 int dbm)
10967{
10968 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010969 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10971 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010972 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010973
10974 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10976 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10977 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010978 status = wlan_hdd_validate_context(pHddCtx);
10979
10980 if (0 != status)
10981 {
10982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10983 "%s: HDD context is not valid", __func__);
10984 return status;
10985 }
10986
10987 hHal = pHddCtx->hHal;
10988
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010989 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10990 dbm, ccmCfgSetCallback,
10991 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010993 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10995 return -EIO;
10996 }
10997
10998 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10999 dbm);
11000
11001 switch(type)
11002 {
11003 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11004 /* Fall through */
11005 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11006 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11009 __func__);
11010 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 }
11012 break;
11013 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 __func__);
11016 return -EOPNOTSUPP;
11017 break;
11018 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11020 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 return -EIO;
11022 }
11023
11024 return 0;
11025}
11026
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011027static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11028#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11029 struct wireless_dev *wdev,
11030#endif
11031#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11032 enum tx_power_setting type,
11033#else
11034 enum nl80211_tx_power_setting type,
11035#endif
11036 int dbm)
11037{
11038 int ret;
11039 vos_ssr_protect(__func__);
11040 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11041#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11042 wdev,
11043#endif
11044#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11045 type,
11046#else
11047 type,
11048#endif
11049 dbm);
11050 vos_ssr_unprotect(__func__);
11051
11052 return ret;
11053}
11054
Jeff Johnson295189b2012-06-20 16:38:30 -070011055/*
11056 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11057 * This function is used to read the txpower
11058 */
Yue Maf49ba872013-08-19 12:04:25 -070011059static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11060#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11061 struct wireless_dev *wdev,
11062#endif
11063 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011064{
11065
11066 hdd_adapter_t *pAdapter;
11067 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011068 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011069
Jeff Johnsone7245742012-09-05 17:12:55 -070011070 ENTER();
11071
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011072 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011074 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011075 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11077 "%s: HDD context is not valid", __func__);
11078 *dbm = 0;
11079 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011080 }
11081
Jeff Johnson295189b2012-06-20 16:38:30 -070011082 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11083 if (NULL == pAdapter)
11084 {
11085 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11086 return -ENOENT;
11087 }
11088
11089 wlan_hdd_get_classAstats(pAdapter);
11090 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11091
Jeff Johnsone7245742012-09-05 17:12:55 -070011092 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 return 0;
11094}
11095
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011096static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 u8* mac, struct station_info *sinfo)
11098{
11099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11100 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11101 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011102 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011103
11104 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11105 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011106
11107 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11108 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11109 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11110 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11111 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11112 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11113 tANI_U16 maxRate = 0;
11114 tANI_U16 myRate;
11115 tANI_U16 currentRate = 0;
11116 tANI_U8 maxSpeedMCS = 0;
11117 tANI_U8 maxMCSIdx = 0;
11118 tANI_U8 rateFlag = 1;
11119 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011120 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011121 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011122
Leo Chang6f8870f2013-03-26 18:11:36 -070011123#ifdef WLAN_FEATURE_11AC
11124 tANI_U32 vht_mcs_map;
11125 eDataRate11ACMaxMcs vhtMaxMcs;
11126#endif /* WLAN_FEATURE_11AC */
11127
Jeff Johnsone7245742012-09-05 17:12:55 -070011128 ENTER();
11129
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11131 (0 == ssidlen))
11132 {
11133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11134 " Invalid ssidlen, %d", __func__, ssidlen);
11135 /*To keep GUI happy*/
11136 return 0;
11137 }
11138
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011139 status = wlan_hdd_validate_context(pHddCtx);
11140
11141 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11144 "%s: HDD context is not valid", __func__);
11145 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011146 }
11147
Jeff Johnson295189b2012-06-20 16:38:30 -070011148
Kiet Lam3b17fc82013-09-27 05:24:08 +053011149 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11150 sinfo->filled |= STATION_INFO_SIGNAL;
11151
c_hpothu09f19542014-05-30 21:53:31 +053011152 wlan_hdd_get_station_stats(pAdapter);
11153 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11154
11155 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011156 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11157 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11158 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11159 {
11160 rate_flags = pAdapter->maxRateFlags;
11161 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011162
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 //convert to the UI units of 100kbps
11164 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11165
11166#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011167 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 -070011168 sinfo->signal,
11169 pCfg->reportMaxLinkSpeed,
11170 myRate,
11171 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011172 (int) pCfg->linkSpeedRssiMid,
11173 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011174 (int) rate_flags,
11175 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011176#endif //LINKSPEED_DEBUG_ENABLED
11177
11178 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11179 {
11180 // we do not want to necessarily report the current speed
11181 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11182 {
11183 // report the max possible speed
11184 rssidx = 0;
11185 }
11186 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11187 {
11188 // report the max possible speed with RSSI scaling
11189 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11190 {
11191 // report the max possible speed
11192 rssidx = 0;
11193 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011194 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 {
11196 // report middle speed
11197 rssidx = 1;
11198 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011199 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11200 {
11201 // report middle speed
11202 rssidx = 2;
11203 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 else
11205 {
11206 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011207 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 }
11209 }
11210 else
11211 {
11212 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11213 hddLog(VOS_TRACE_LEVEL_ERROR,
11214 "%s: Invalid value for reportMaxLinkSpeed: %u",
11215 __func__, pCfg->reportMaxLinkSpeed);
11216 rssidx = 0;
11217 }
11218
11219 maxRate = 0;
11220
11221 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011222 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11223 OperationalRates, &ORLeng))
11224 {
11225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11226 /*To keep GUI happy*/
11227 return 0;
11228 }
11229
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 for (i = 0; i < ORLeng; i++)
11231 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011232 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 {
11234 /* Validate Rate Set */
11235 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11236 {
11237 currentRate = supported_data_rate[j].supported_rate[rssidx];
11238 break;
11239 }
11240 }
11241 /* Update MAX rate */
11242 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11243 }
11244
11245 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011246 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11247 ExtendedRates, &ERLeng))
11248 {
11249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11250 /*To keep GUI happy*/
11251 return 0;
11252 }
11253
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 for (i = 0; i < ERLeng; i++)
11255 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011256 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 {
11258 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11259 {
11260 currentRate = supported_data_rate[j].supported_rate[rssidx];
11261 break;
11262 }
11263 }
11264 /* Update MAX rate */
11265 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11266 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011267 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011268 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011269 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011270 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011271 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011273 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11274 MCSRates, &MCSLeng))
11275 {
11276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11277 /*To keep GUI happy*/
11278 return 0;
11279 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011281#ifdef WLAN_FEATURE_11AC
11282 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011283 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011285 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011286 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011287 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011289 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011291 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011293 maxMCSIdx = 7;
11294 }
11295 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11296 {
11297 maxMCSIdx = 8;
11298 }
11299 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11300 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011301 //VHT20 is supporting 0~8
11302 if (rate_flags & eHAL_TX_RATE_VHT20)
11303 maxMCSIdx = 8;
11304 else
11305 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011306 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011307
11308 if (rate_flags & eHAL_TX_RATE_VHT80)
11309 {
11310 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11311 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11312 }
11313 else if (rate_flags & eHAL_TX_RATE_VHT40)
11314 {
11315 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11316 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11317 }
11318 else if (rate_flags & eHAL_TX_RATE_VHT20)
11319 {
11320 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11321 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11322 }
11323
Leo Chang6f8870f2013-03-26 18:11:36 -070011324 maxSpeedMCS = 1;
11325 if (currentRate > maxRate)
11326 {
11327 maxRate = currentRate;
11328 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011329
Leo Chang6f8870f2013-03-26 18:11:36 -070011330 }
11331 else
11332#endif /* WLAN_FEATURE_11AC */
11333 {
11334 if (rate_flags & eHAL_TX_RATE_HT40)
11335 {
11336 rateFlag |= 1;
11337 }
11338 if (rate_flags & eHAL_TX_RATE_SGI)
11339 {
11340 rateFlag |= 2;
11341 }
11342
11343 for (i = 0; i < MCSLeng; i++)
11344 {
11345 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11346 for (j = 0; j < temp; j++)
11347 {
11348 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11349 {
11350 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11351 break;
11352 }
11353 }
11354 if ((j < temp) && (currentRate > maxRate))
11355 {
11356 maxRate = currentRate;
11357 maxSpeedMCS = 1;
11358 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11359 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 }
11361 }
11362 }
11363
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011364 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11365 {
11366 maxRate = myRate;
11367 maxSpeedMCS = 1;
11368 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11369 }
11370
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011372 if (((maxRate < myRate) && (0 == rssidx)) ||
11373 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011374 {
11375 maxRate = myRate;
11376 if (rate_flags & eHAL_TX_RATE_LEGACY)
11377 {
11378 maxSpeedMCS = 0;
11379 }
11380 else
11381 {
11382 maxSpeedMCS = 1;
11383 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11384 }
11385 }
11386
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011387 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 {
11389 sinfo->txrate.legacy = maxRate;
11390#ifdef LINKSPEED_DEBUG_ENABLED
11391 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11392#endif //LINKSPEED_DEBUG_ENABLED
11393 }
11394 else
11395 {
11396 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011397#ifdef WLAN_FEATURE_11AC
11398 sinfo->txrate.nss = 1;
11399 if (rate_flags & eHAL_TX_RATE_VHT80)
11400 {
11401 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011402 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011403 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011404 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011405 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011406 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11407 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11408 }
11409 else if (rate_flags & eHAL_TX_RATE_VHT20)
11410 {
11411 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11412 }
11413#endif /* WLAN_FEATURE_11AC */
11414 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11415 {
11416 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11417 if (rate_flags & eHAL_TX_RATE_HT40)
11418 {
11419 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11420 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 if (rate_flags & eHAL_TX_RATE_SGI)
11423 {
11424 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11425 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011426
Jeff Johnson295189b2012-06-20 16:38:30 -070011427#ifdef LINKSPEED_DEBUG_ENABLED
11428 pr_info("Reporting MCS rate %d flags %x\n",
11429 sinfo->txrate.mcs,
11430 sinfo->txrate.flags );
11431#endif //LINKSPEED_DEBUG_ENABLED
11432 }
11433 }
11434 else
11435 {
11436 // report current rate instead of max rate
11437
11438 if (rate_flags & eHAL_TX_RATE_LEGACY)
11439 {
11440 //provide to the UI in units of 100kbps
11441 sinfo->txrate.legacy = myRate;
11442#ifdef LINKSPEED_DEBUG_ENABLED
11443 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11444#endif //LINKSPEED_DEBUG_ENABLED
11445 }
11446 else
11447 {
11448 //must be MCS
11449 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011450#ifdef WLAN_FEATURE_11AC
11451 sinfo->txrate.nss = 1;
11452 if (rate_flags & eHAL_TX_RATE_VHT80)
11453 {
11454 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11455 }
11456 else
11457#endif /* WLAN_FEATURE_11AC */
11458 {
11459 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11460 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 if (rate_flags & eHAL_TX_RATE_SGI)
11462 {
11463 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11464 }
11465 if (rate_flags & eHAL_TX_RATE_HT40)
11466 {
11467 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11468 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011469#ifdef WLAN_FEATURE_11AC
11470 else if (rate_flags & eHAL_TX_RATE_VHT80)
11471 {
11472 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11473 }
11474#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011475#ifdef LINKSPEED_DEBUG_ENABLED
11476 pr_info("Reporting actual MCS rate %d flags %x\n",
11477 sinfo->txrate.mcs,
11478 sinfo->txrate.flags );
11479#endif //LINKSPEED_DEBUG_ENABLED
11480 }
11481 }
11482 sinfo->filled |= STATION_INFO_TX_BITRATE;
11483
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011484 sinfo->tx_packets =
11485 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11486 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11487 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11488 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11489
11490 sinfo->tx_retries =
11491 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11492 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11493 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11494 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11495
11496 sinfo->tx_failed =
11497 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11498 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11499 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11500 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11501
11502 sinfo->filled |=
11503 STATION_INFO_TX_PACKETS |
11504 STATION_INFO_TX_RETRIES |
11505 STATION_INFO_TX_FAILED;
11506
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11508 TRACE_CODE_HDD_CFG80211_GET_STA,
11509 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011510 EXIT();
11511 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011512}
11513
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011514static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11515 u8* mac, struct station_info *sinfo)
11516{
11517 int ret;
11518
11519 vos_ssr_protect(__func__);
11520 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11521 vos_ssr_unprotect(__func__);
11522
11523 return ret;
11524}
11525
11526static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011527 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011528{
11529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011530 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011532 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011533
Jeff Johnsone7245742012-09-05 17:12:55 -070011534 ENTER();
11535
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 if (NULL == pAdapter)
11537 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 return -ENODEV;
11540 }
11541
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011542 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11543 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11544 pAdapter->sessionId, timeout));
11545
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011546 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011547 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011548
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011549 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11552 "%s: HDD context is not valid", __func__);
11553 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011554 }
11555
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011556 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11557 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11558 (pHddCtx->cfg_ini->fhostArpOffload) &&
11559 (eConnectionState_Associated ==
11560 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11561 {
Amar Singhald53568e2013-09-26 11:03:45 -070011562
11563 hddLog(VOS_TRACE_LEVEL_INFO,
11564 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011565 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011566 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11567 {
11568 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011569 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011570 __func__, vos_status);
11571 }
11572 }
11573
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 /**The get power cmd from the supplicant gets updated by the nl only
11575 *on successful execution of the function call
11576 *we are oppositely mapped w.r.t mode in the driver
11577 **/
11578 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11579
Kiet Lam94fd2922014-06-18 19:12:43 -070011580 if (!mode)
11581 {
11582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11583 "%s: DHCP start indicated through power save", __func__);
11584
11585 pHddCtx->btCoexModeSet = TRUE;
11586 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11587 pAdapter->sessionId);
11588 }
11589 else
11590 {
11591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11592 "%s: DHCP stop indicated through power save", __func__);
11593
11594 pHddCtx->btCoexModeSet = FALSE;
11595 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11596 pAdapter->sessionId);
11597 }
11598
Jeff Johnsone7245742012-09-05 17:12:55 -070011599 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 if (VOS_STATUS_E_FAILURE == vos_status)
11601 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11603 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 return -EINVAL;
11605 }
11606 return 0;
11607}
11608
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011609static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11610 struct net_device *dev, bool mode, int timeout)
11611{
11612 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011613
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011614 vos_ssr_protect(__func__);
11615 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11616 vos_ssr_unprotect(__func__);
11617
11618 return ret;
11619}
Jeff Johnson295189b2012-06-20 16:38:30 -070011620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11621static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11622 struct net_device *netdev,
11623 u8 key_index)
11624{
Jeff Johnsone7245742012-09-05 17:12:55 -070011625 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 return 0;
11627}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011628#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011629
11630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11631static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11632 struct net_device *dev,
11633 struct ieee80211_txq_params *params)
11634{
Jeff Johnsone7245742012-09-05 17:12:55 -070011635 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 return 0;
11637}
11638#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11639static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11640 struct ieee80211_txq_params *params)
11641{
Jeff Johnsone7245742012-09-05 17:12:55 -070011642 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 return 0;
11644}
11645#endif //LINUX_VERSION_CODE
11646
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011647static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 struct net_device *dev, u8 *mac)
11649{
11650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011651 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011652 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011653 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011654 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011655
Jeff Johnsone7245742012-09-05 17:12:55 -070011656 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011657
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011658 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011661 return -EINVAL;
11662 }
11663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11665 TRACE_CODE_HDD_CFG80211_DEL_STA,
11666 pAdapter->sessionId, pAdapter->device_mode));
11667
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011668 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11669 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011671 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011672 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11674 "%s: HDD context is not valid", __func__);
11675 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011676 }
11677
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 )
11681 {
11682 if( NULL == mac )
11683 {
11684 v_U16_t i;
11685 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11686 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011687 if ((pAdapter->aStaInfo[i].isUsed) &&
11688 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 {
11690 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11691 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011692 "%s: Delete STA with MAC::"
11693 MAC_ADDRESS_STR,
11694 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011695 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11696 if (VOS_IS_STATUS_SUCCESS(vos_status))
11697 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 }
11699 }
11700 }
11701 else
11702 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011703
11704 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11705 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11706 {
11707 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011708 "%s: Skip this DEL STA as this is not used::"
11709 MAC_ADDRESS_STR,
11710 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011711 return -ENOENT;
11712 }
11713
11714 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11715 {
11716 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011717 "%s: Skip this DEL STA as deauth is in progress::"
11718 MAC_ADDRESS_STR,
11719 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011720 return -ENOENT;
11721 }
11722
11723 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11724
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 hddLog(VOS_TRACE_LEVEL_INFO,
11726 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011727 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011728 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011729 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011730
11731 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11732 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11733 {
11734 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11735 hddLog(VOS_TRACE_LEVEL_INFO,
11736 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011737 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011738 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011739 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011740 return -ENOENT;
11741 }
11742
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 }
11744 }
11745
11746 EXIT();
11747
11748 return 0;
11749}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011750static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11751 struct net_device *dev, u8 *mac)
11752{
11753 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011754
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011755 vos_ssr_protect(__func__);
11756 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11757 vos_ssr_unprotect(__func__);
11758
11759 return ret;
11760}
11761
11762static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011763 struct net_device *dev, u8 *mac, struct station_parameters *params)
11764{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011766 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011767#ifdef FEATURE_WLAN_TDLS
11768 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011769 ENTER();
Sushant Kaushik10728722014-05-14 16:20:25 +053011770 if (NULL == pAdapter)
11771 {
11772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11773 "%s: HDD adapter context is Null", __func__);
11774 return -ENODEV;
11775 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11777 TRACE_CODE_HDD_CFG80211_ADD_STA,
11778 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011779 mask = params->sta_flags_mask;
11780
11781 set = params->sta_flags_set;
11782
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011783#ifdef WLAN_FEATURE_TDLS_DEBUG
11784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11785 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11786 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11787#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011788
11789 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11790 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011791 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011792 }
11793 }
11794#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011795 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796}
11797
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011798static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11799 struct net_device *dev, u8 *mac, struct station_parameters *params)
11800{
11801 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011802
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011803 vos_ssr_protect(__func__);
11804 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11805 vos_ssr_unprotect(__func__);
11806
11807 return ret;
11808}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011809#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011810
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011811static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011812 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011813{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011814 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011816 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011817 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011819 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011820 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011821 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011822 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11823 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011824
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011825 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011826 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011829 return -EINVAL;
11830 }
11831
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011832 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11833 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011834
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011835 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011836 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11838 "%s: HDD context is not valid", __func__);
11839 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011840 }
11841
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011842 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011843 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011844 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011845
Agarwal Ashish3da95242014-05-21 14:57:17 +053011846 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011847 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011848 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849 pmksa->bssid, WNI_CFG_BSSID_LEN))
11850 {
11851 /* BSSID matched previous entry. Overwrite it. */
11852 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011853 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011854 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011855 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011856 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011857 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011859 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011860 dump_bssid(pmksa->bssid);
11861 dump_pmkid(halHandle, pmksa->pmkid);
11862 break;
11863 }
11864 }
11865
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011866 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011867 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011868
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011869 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011870 {
11871 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011872 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011874 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011875 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011876 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011877 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11878 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 dump_bssid(pmksa->bssid);
11880 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011881 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011882 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011883 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11884 pHddStaCtx->PMKIDCacheIndex++;
11885 else
11886 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011887 }
11888
11889
11890 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011891 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11892 __func__, pHddStaCtx->PMKIDCacheIndex );
11893
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011894 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011896 pHddStaCtx->PMKIDCache,
11897 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011898 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11899 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11900 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011901 return 0;
11902}
11903
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011904static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11905 struct cfg80211_pmksa *pmksa)
11906{
11907 int ret;
11908
11909 vos_ssr_protect(__func__);
11910 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11911 vos_ssr_unprotect(__func__);
11912
11913 return ret;
11914}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011915
Wilson Yang6507c4e2013-10-01 20:11:19 -070011916
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011917static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011918 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011919{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011920 tANI_U32 j=0;
11921 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011922 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011923 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011924 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011925 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011926 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011927
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011928 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11929 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011930
11931 /* Validate pAdapter */
11932 if (NULL == pAdapter)
11933 {
11934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11935 return -EINVAL;
11936 }
11937
11938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11939 status = wlan_hdd_validate_context(pHddCtx);
11940
11941 if (0 != status)
11942 {
11943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11944 "%s: HDD context is not valid", __func__);
11945 return status;
11946 }
11947
11948 /*Retrieve halHandle*/
11949 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011950 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011951
11952 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011953 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011954 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011955 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11956 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011957 }
11958
11959 /*find the matching PMKSA entry from j=0 to (index-1),
11960 * and delete the matched one
11961 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011962 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011963 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011964 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011965 pmksa->bssid,
11966 WNI_CFG_BSSID_LEN))
11967 {
11968 /* BSSID matched entry */
11969 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011970 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011971 {
11972 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011973 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11974 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11975 VOS_MAC_ADDR_SIZE);
11976 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11977 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11978 CSR_RSN_PMKID_SIZE);
11979 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011980
11981 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011982 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11983 VOS_MAC_ADDR_SIZE);
11984 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11985 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011986 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011987 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011988 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011989 if (eHAL_STATUS_SUCCESS !=
11990 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011991 {
11992 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011993 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011994 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011995 }
11996
11997 dump_bssid(pmksa->bssid);
11998 dump_pmkid(halHandle,pmksa->pmkid);
11999
12000 break;
12001 }
12002 }
12003
12004 /* we compare all entries,but cannot find matching entry */
12005 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12006 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012007 hddLog(VOS_TRACE_LEVEL_FATAL,
12008 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12009 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012010 dump_bssid(pmksa->bssid);
12011 dump_pmkid(halHandle, pmksa->pmkid);
12012 return -EINVAL;
12013 }
Wilson Yangef657d32014-01-15 19:19:23 -080012014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012015}
12016
Wilson Yang6507c4e2013-10-01 20:11:19 -070012017
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012018static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12019 struct cfg80211_pmksa *pmksa)
12020{
12021 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012022
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012023 vos_ssr_protect(__func__);
12024 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12025 vos_ssr_unprotect(__func__);
12026
12027 return ret;
12028
12029}
12030
12031static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012032{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012033 tANI_U32 j=0;
12034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012035 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012036 tHalHandle halHandle;
12037 hdd_context_t *pHddCtx;
12038 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012039 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012040
12041 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12042
12043 /* Validate pAdapter */
12044 if (NULL == pAdapter)
12045 {
12046 hddLog(VOS_TRACE_LEVEL_ERROR,
12047 "%s: Invalid Adapter" ,__func__);
12048 return -EINVAL;
12049 }
12050
12051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12052 status = wlan_hdd_validate_context(pHddCtx);
12053
12054 if (0 != status)
12055 {
12056 hddLog(VOS_TRACE_LEVEL_ERROR,
12057 "%s: HDD context is not valid", __func__);
12058 return status;
12059 }
12060
12061 /*Retrieve halHandle*/
12062 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012063 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012064
12065 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012066 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012067 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012069 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012070 }
12071
12072 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012073 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012074 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012075 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012076 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012077 if (eHAL_STATUS_SUCCESS !=
12078 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012079 {
12080 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12081 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012082 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012083 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012084 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012085 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12086 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12087 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012088
Agarwal Ashish3da95242014-05-21 14:57:17 +053012089 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012090 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012092
12093static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12094{
12095 int ret;
12096
12097 vos_ssr_protect(__func__);
12098 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12099 vos_ssr_unprotect(__func__);
12100
12101 return ret;
12102}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103#endif
12104
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012105#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012106static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12107 struct net_device *dev,
12108 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012109{
12110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12111 hdd_station_ctx_t *pHddStaCtx;
12112
12113 if (NULL == pAdapter)
12114 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012116 return -ENODEV;
12117 }
12118
12119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12120
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12122 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12123 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012124 // Added for debug on reception of Re-assoc Req.
12125 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12126 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012127 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012128 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012129 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012130 }
12131
12132#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012133 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012134 ftie->ie_len);
12135#endif
12136
12137 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012138 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12139 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012140 ftie->ie_len);
12141 return 0;
12142}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012143
12144static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12145 struct net_device *dev,
12146 struct cfg80211_update_ft_ies_params *ftie)
12147{
12148 int ret;
12149
12150 vos_ssr_protect(__func__);
12151 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12152 vos_ssr_unprotect(__func__);
12153
12154 return ret;
12155}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012156#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012157
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012158#ifdef FEATURE_WLAN_SCAN_PNO
12159
12160void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12161 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12162{
12163 int ret;
12164 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12165 hdd_context_t *pHddCtx;
12166
Nirav Shah80830bf2013-12-31 16:35:12 +053012167 ENTER();
12168
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012169 if (NULL == pAdapter)
12170 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012172 "%s: HDD adapter is Null", __func__);
12173 return ;
12174 }
12175
12176 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12177 if (NULL == pHddCtx)
12178 {
12179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12180 "%s: HDD context is Null!!!", __func__);
12181 return ;
12182 }
12183
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012184 spin_lock(&pHddCtx->schedScan_lock);
12185 if (TRUE == pHddCtx->isWiphySuspended)
12186 {
12187 pHddCtx->isSchedScanUpdatePending = TRUE;
12188 spin_unlock(&pHddCtx->schedScan_lock);
12189 hddLog(VOS_TRACE_LEVEL_INFO,
12190 "%s: Update cfg80211 scan database after it resume", __func__);
12191 return ;
12192 }
12193 spin_unlock(&pHddCtx->schedScan_lock);
12194
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012195 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12196
12197 if (0 > ret)
12198 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12199
12200 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12202 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012203}
12204
12205/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012206 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012207 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012208 */
12209static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12210{
12211 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12212 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012213 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012214 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12215 int status = 0;
12216 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12217
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012218 /* The current firmware design does not allow PNO during any
12219 * active sessions. Hence, determine the active sessions
12220 * and return a failure.
12221 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012222 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12223 {
12224 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012225 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012226
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012227 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12228 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12229 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12230 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12231 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12232 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012233 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012234 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012235 }
12236 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12237 pAdapterNode = pNext;
12238 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012239 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012240}
12241
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012242void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12243{
12244 hdd_adapter_t *pAdapter = callbackContext;
12245 hdd_context_t *pHddCtx;
12246
12247 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12248 {
12249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12250 FL("Invalid adapter or adapter has invalid magic"));
12251 return;
12252 }
12253
12254 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12255 if (0 != wlan_hdd_validate_context(pHddCtx))
12256 {
12257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12258 FL("HDD context is not valid"));
12259 return;
12260 }
12261
12262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12263 FL("PNO enable response status = %d"), status);
12264
12265 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12266 complete(&pAdapter->pno_comp_var);
12267}
12268
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012269/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012270 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12271 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012272 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012273static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012274 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12275{
12276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12277 tpSirPNOScanReq pPnoRequest = NULL;
12278 hdd_context_t *pHddCtx;
12279 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012280 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012281 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12282 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012283 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12284 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012285 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012286
12287 if (NULL == pAdapter)
12288 {
Sushant Kaushik10728722014-05-14 16:20:25 +053012289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012290 "%s: HDD adapter is Null", __func__);
12291 return -ENODEV;
12292 }
12293
12294 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012295 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012296
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012297 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012298 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12300 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012301 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012302 }
12303
12304 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12305 if (NULL == hHal)
12306 {
12307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12308 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012309 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012310 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012311
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012312 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012313 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012314 {
12315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12316 "%s: aborting the existing scan is unsuccessfull", __func__);
12317 return -EBUSY;
12318 }
12319
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012320 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012321 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012323 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012324 return -EBUSY;
12325 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012326
c_hpothu37f21312014-04-09 21:49:54 +053012327 if (TRUE == pHddCtx->isPnoEnable)
12328 {
12329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12330 FL("already PNO is enabled"));
12331 return -EBUSY;
12332 }
12333 pHddCtx->isPnoEnable = TRUE;
12334
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012335 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12336 if (NULL == pPnoRequest)
12337 {
12338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12339 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012340 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012341 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012342 }
12343
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012344 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012345 pPnoRequest->enable = 1; /*Enable PNO */
12346 pPnoRequest->ucNetworksCount = request->n_match_sets;
12347
12348 if (( !pPnoRequest->ucNetworksCount ) ||
12349 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12350 {
12351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012352 "%s: Network input is not correct %d Max Network supported is %d",
12353 __func__, pPnoRequest->ucNetworksCount,
12354 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012355 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012356 goto error;
12357 }
12358
12359 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12360 {
12361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012362 "%s: Incorrect number of channels %d",
12363 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012364 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012365 goto error;
12366 }
12367
12368 /* Framework provides one set of channels(all)
12369 * common for all saved profile */
12370 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12371 channels_allowed, &num_channels_allowed))
12372 {
12373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12374 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012375 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012376 goto error;
12377 }
12378 /* Checking each channel against allowed channel list */
12379 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012380 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012381 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012382 char chList [(request->n_channels*5)+1];
12383 int len;
12384 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012385 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012386 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012387 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012388 if (request->channels[i]->hw_value == channels_allowed[indx])
12389 {
12390 valid_ch[num_ch++] = request->channels[i]->hw_value;
12391 len += snprintf(chList+len, 5, "%d ",
12392 request->channels[i]->hw_value);
12393 break ;
12394 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012395 }
12396 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012397 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12398 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012399
12400 /* Filling per profile params */
12401 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12402 {
12403 pPnoRequest->aNetworks[i].ssId.length =
12404 request->match_sets[i].ssid.ssid_len;
12405
12406 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12407 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12408 {
12409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012410 "%s: SSID Len %d is not correct for network %d",
12411 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012412 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012413 goto error;
12414 }
12415
12416 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12417 request->match_sets[i].ssid.ssid,
12418 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12420 "%s: SSID of network %d is %s ", __func__,
12421 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012422 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12423 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12424 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12425
12426 /*Copying list of valid channel into request */
12427 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12428 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12429
12430 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12431 }
12432
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012434 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012435 if ((0 < request->ie_len) && (NULL != request->ie))
12436 {
12437 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12438 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12439 pPnoRequest->us24GProbeTemplateLen);
12440
12441 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12442 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12443 pPnoRequest->us5GProbeTemplateLen);
12444 }
12445
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012446 /* Driver gets only one time interval which is hardcoded in
12447 * supplicant for 10000ms. Taking power consumption into account 6 timers
12448 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12449 * 80,160,320 secs. And number of scan cycle for each timer
12450 * is configurable through INI param gPNOScanTimerRepeatValue.
12451 * If it is set to 0 only one timer will be used and PNO scan cycle
12452 * will be repeated after each interval specified by supplicant
12453 * till PNO is disabled.
12454 */
12455 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12456 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12457 else
12458 pPnoRequest->scanTimers.ucScanTimersCount =
12459 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12460
12461 tempInterval = (request->interval)/1000;
12462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12463 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12464 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12465 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12466 {
12467 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12468 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12469 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12470 tempInterval *= 2;
12471 }
12472 //Repeat last timer until pno disabled.
12473 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12474
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012475 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012476
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012477 INIT_COMPLETION(pAdapter->pno_comp_var);
12478 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12479 pPnoRequest->callbackContext = pAdapter;
12480 pAdapter->pno_req_status = 0;
12481
Nirav Shah80830bf2013-12-31 16:35:12 +053012482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12483 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12484 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12485 pPnoRequest->scanTimers.ucScanTimersCount);
12486
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012487 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12488 pPnoRequest, pAdapter->sessionId,
12489 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12490 if (eHAL_STATUS_SUCCESS != status)
12491 {
12492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012493 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012494 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012495 goto error;
12496 }
12497
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012498 ret = wait_for_completion_timeout(
12499 &pAdapter->pno_comp_var,
12500 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12501 if (0 >= ret)
12502 {
12503 // Did not receive the response for PNO enable in time.
12504 // Assuming the PNO enable was success.
12505 // Returning error from here, because we timeout, results
12506 // in side effect of Wifi (Wifi Setting) not to work.
12507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12508 FL("Timed out waiting for PNO to be Enabled"));
12509 ret = 0;
12510 goto error;
12511 }
12512
12513 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012514 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012515
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012516error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12518 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012519 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012520 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012521 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012522}
12523
12524/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012525 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12526 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012527 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012528static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12529 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12530{
12531 int ret;
12532
12533 vos_ssr_protect(__func__);
12534 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12535 vos_ssr_unprotect(__func__);
12536
12537 return ret;
12538}
12539
12540/*
12541 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12542 * Function to disable PNO
12543 */
12544static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012545 struct net_device *dev)
12546{
12547 eHalStatus status = eHAL_STATUS_FAILURE;
12548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12549 hdd_context_t *pHddCtx;
12550 tHalHandle hHal;
12551 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012552 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012553
12554 ENTER();
12555
12556 if (NULL == pAdapter)
12557 {
Sushant Kaushik10728722014-05-14 16:20:25 +053012558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012559 "%s: HDD adapter is Null", __func__);
12560 return -ENODEV;
12561 }
12562
12563 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012564
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012565 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012566 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012568 "%s: HDD context is Null", __func__);
12569 return -ENODEV;
12570 }
12571
12572 /* The return 0 is intentional when isLogpInProgress and
12573 * isLoadUnloadInProgress. We did observe a crash due to a return of
12574 * failure in sched_scan_stop , especially for a case where the unload
12575 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12576 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12577 * success. If it returns a failure , then its next invocation due to the
12578 * clean up of the second interface will have the dev pointer corresponding
12579 * to the first one leading to a crash.
12580 */
12581 if (pHddCtx->isLogpInProgress)
12582 {
12583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12584 "%s: LOGP in Progress. Ignore!!!", __func__);
12585 return ret;
12586 }
12587
Mihir Shete18156292014-03-11 15:38:30 +053012588 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012589 {
12590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12591 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12592 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012593 }
12594
12595 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12596 if (NULL == hHal)
12597 {
12598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12599 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012600 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012601 }
12602
12603 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12604 if (NULL == pPnoRequest)
12605 {
12606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12607 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012608 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012609 }
12610
12611 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12612 pPnoRequest->enable = 0; /* Disable PNO */
12613 pPnoRequest->ucNetworksCount = 0;
12614
12615 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12616 pAdapter->sessionId,
12617 NULL, pAdapter);
12618 if (eHAL_STATUS_SUCCESS != status)
12619 {
12620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12621 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012622 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012623 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012624 }
c_hpothu37f21312014-04-09 21:49:54 +053012625 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012626
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012627error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012629 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012630 vos_mem_free(pPnoRequest);
12631
12632 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012633 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012634}
12635
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012636/*
12637 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12638 * NL interface to disable PNO
12639 */
12640static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12641 struct net_device *dev)
12642{
12643 int ret;
12644
12645 vos_ssr_protect(__func__);
12646 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12647 vos_ssr_unprotect(__func__);
12648
12649 return ret;
12650}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012651#endif /*FEATURE_WLAN_SCAN_PNO*/
12652
12653
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012654#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012655#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012656static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12657 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012658 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12659#else
12660static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12661 u8 *peer, u8 action_code, u8 dialog_token,
12662 u16 status_code, const u8 *buf, size_t len)
12663#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012664{
12665
12666 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12667 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012668 u8 peerMac[6];
12669 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012670 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012671 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012672 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012673#if !(TDLS_MGMT_VERSION2)
12674 u32 peer_capability = 0;
12675#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012676 tANI_U16 numCurrTdlsPeers;
Sushant Kaushik10728722014-05-14 16:20:25 +053012677 if (NULL == pAdapter)
12678 {
12679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12680 "%s: HDD adapter context is Null", __func__);
12681 return -ENODEV;
12682 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012683 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12684 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12685 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012686 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012689 "Invalid arguments");
12690 return -EINVAL;
12691 }
12692
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012693 if (pHddCtx->isLogpInProgress)
12694 {
12695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12696 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012697 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012698 return -EBUSY;
12699 }
12700
Hoonki Lee27511902013-03-14 18:19:06 -070012701 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012702 {
Hoonki Lee27511902013-03-14 18:19:06 -070012703 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12704 "%s: TDLS mode is disabled OR not enabled in FW."
12705 MAC_ADDRESS_STR " action %d declined.",
12706 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012707 return -ENOTSUPP;
12708 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012709
Hoonki Lee27511902013-03-14 18:19:06 -070012710 /* other than teardown frame, other mgmt frames are not sent if disabled */
12711 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12712 {
12713 /* if tdls_mode is disabled to respond to peer's request */
12714 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12715 {
12716 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12717 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012718 " TDLS mode is disabled. action %d declined.",
12719 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012720
12721 return -ENOTSUPP;
12722 }
12723 }
12724
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012725 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12726 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012727 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012728 {
12729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012730 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012731 " TDLS setup is ongoing. action %d declined.",
12732 __func__, MAC_ADDR_ARRAY(peer), action_code);
12733 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012734 }
12735 }
12736
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012737 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12738 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012739 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012740 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12741 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012742 {
12743 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12744 we return error code at 'add_station()'. Hence we have this
12745 check again in addtion to add_station().
12746 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012747 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012748 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12750 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012751 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12752 __func__, MAC_ADDR_ARRAY(peer), action_code,
12753 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012754 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012755 }
12756 else
12757 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012758 /* maximum reached. tweak to send error code to peer and return
12759 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012760 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12762 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012763 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12764 __func__, MAC_ADDR_ARRAY(peer), status_code,
12765 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012766 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012767 /* fall through to send setup resp with failure status
12768 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012769 }
12770 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012771 else
12772 {
12773 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012774 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012775 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012776 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012778 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12779 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012780 return -EPERM;
12781 }
12782 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012783 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012784 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012785
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012786#ifdef WLAN_FEATURE_TDLS_DEBUG
12787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012788 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012789 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12790 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012791#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012792
Hoonki Leea34dd892013-02-05 22:56:02 -080012793 /*Except teardown responder will not be used so just make 0*/
12794 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012795 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012796 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012797
12798 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012799 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012800
12801 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12802 responder = pTdlsPeer->is_responder;
12803 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012804 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012806 "%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 -070012807 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12808 dialog_token, status_code, len);
12809 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012810 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012811 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012812
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012813 /* For explicit trigger of DIS_REQ come out of BMPS for
12814 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012815 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012816 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12817 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012818 {
12819 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12820 {
12821 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012822 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012823 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12824 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012825 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12826 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012827 }
12828
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012829 /* make sure doesn't call send_mgmt() while it is pending */
12830 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12831 {
12832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012833 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012834 __func__, MAC_ADDR_ARRAY(peer), action_code);
12835 return -EBUSY;
12836 }
12837
12838 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012839 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12840
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012841 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012842 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012843
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012844 if (VOS_STATUS_SUCCESS != status)
12845 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12847 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012848 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012849 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012850 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012851 }
12852
Hoonki Leed37cbb32013-04-20 00:31:14 -070012853 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12854 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12855
12856 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012857 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012859 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012860 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012861 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012862
12863 if (pHddCtx->isLogpInProgress)
12864 {
12865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12866 "%s: LOGP in Progress. Ignore!!!", __func__);
12867 return -EAGAIN;
12868 }
12869
Hoonki Leed37cbb32013-04-20 00:31:14 -070012870 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012871 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012872 }
12873
Gopichand Nakkala05922802013-03-14 12:23:19 -070012874 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012875 {
12876 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012877 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012878 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012879
Hoonki Leea34dd892013-02-05 22:56:02 -080012880 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12881 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012882 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012883 }
12884 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12885 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012886 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012887 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012888
12889 return 0;
12890}
12891
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012892static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012893 u8 *peer, enum nl80211_tdls_operation oper)
12894{
12895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12896 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012897 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012898 hddTdlsPeer_t *pTdlsPeer;
Sushant Kaushik10728722014-05-14 16:20:25 +053012899 if (NULL == pAdapter)
12900 {
12901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12902 "%s: HDD adapter context is Null", __func__);
12903 return -ENODEV;
12904 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12906 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12907 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012908 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012909 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012911 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012912 return -EINVAL;
12913 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012915 status = wlan_hdd_validate_context(pHddCtx);
12916
12917 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12920 "%s: HDD context is not valid", __func__);
12921 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012922 }
12923
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012924
12925 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012926 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012927 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012929 "TDLS Disabled in INI OR not enabled in FW. "
12930 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012931 return -ENOTSUPP;
12932 }
12933
12934 switch (oper) {
12935 case NL80211_TDLS_ENABLE_LINK:
12936 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012937 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012938 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012939 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012940
Sunil Dutt41de4e22013-11-14 18:09:02 +053012941 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12942
12943 if ( NULL == pTdlsPeer ) {
12944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12945 " (oper %d) not exsting. ignored",
12946 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12947 return -EINVAL;
12948 }
12949
12950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12951 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12952 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12953 "NL80211_TDLS_ENABLE_LINK");
12954
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012955 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12956 {
12957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12958 MAC_ADDRESS_STR " failed",
12959 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12960 return -EINVAL;
12961 }
12962
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012963 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012964 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012965 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012966
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012967 if (0 != wlan_hdd_tdls_get_link_establish_params(
12968 pAdapter, peer,&tdlsLinkEstablishParams)) {
12969 return -EINVAL;
12970 }
12971 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012972
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012973 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12974 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12975 /* Send TDLS peer UAPSD capabilities to the firmware and
12976 * register with the TL on after the response for this operation
12977 * is received .
12978 */
12979 ret = wait_for_completion_interruptible_timeout(
12980 &pAdapter->tdls_link_establish_req_comp,
12981 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12982 if (ret <= 0)
12983 {
12984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12985 "%s: Link Establish Request Faled Status %ld",
12986 __func__, ret);
12987 return -EINVAL;
12988 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012989 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012990 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012991 /* Mark TDLS client Authenticated .*/
12992 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12993 pTdlsPeer->staId,
12994 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012995 if (VOS_STATUS_SUCCESS == status)
12996 {
Hoonki Lee14621352013-04-16 17:51:19 -070012997 if (pTdlsPeer->is_responder == 0)
12998 {
12999 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13000
13001 wlan_hdd_tdls_timer_restart(pAdapter,
13002 &pTdlsPeer->initiatorWaitTimeoutTimer,
13003 WAIT_TIME_TDLS_INITIATOR);
13004 /* suspend initiator TX until it receives direct packet from the
13005 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13006 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13007 &staId, NULL);
13008 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013009 wlan_hdd_tdls_increment_peer_count(pAdapter);
13010 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013011 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013012
13013 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013014 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13015 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013016 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013017 int ac;
13018 uint8 ucAc[4] = { WLANTL_AC_VO,
13019 WLANTL_AC_VI,
13020 WLANTL_AC_BK,
13021 WLANTL_AC_BE };
13022 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13023 for(ac=0; ac < 4; ac++)
13024 {
13025 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13026 pTdlsPeer->staId, ucAc[ac],
13027 tlTid[ac], tlTid[ac], 0, 0,
13028 WLANTL_BI_DIR );
13029 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013030 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013031 }
13032
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013033 }
13034 break;
13035 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013036 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013037 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13038
13039 if ( NULL == pTdlsPeer ) {
13040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13041 " (oper %d) not exsting. ignored",
13042 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13043 return -EINVAL;
13044 }
13045
13046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13047 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13048 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13049 "NL80211_TDLS_DISABLE_LINK");
13050
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013051 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013052 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013053 long status;
13054
13055 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13056
Lee Hoonkic1262f22013-01-24 21:59:00 -080013057 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13058 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013059
13060 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13061 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13062 if (status <= 0)
13063 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013064 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13066 "%s: Del station failed status %ld",
13067 __func__, status);
13068 return -EPERM;
13069 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013070 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013071 }
13072 else
13073 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13075 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013076 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013077 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013078 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013079 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013080 {
13081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13082 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13083 __func__, MAC_ADDR_ARRAY(peer));
13084
13085 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13086 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13087
13088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13089 " %s TDLS External control and Implicit Trigger not enabled ",
13090 __func__);
13091 return -ENOTSUPP;
13092 }
13093
Sunil Dutt41de4e22013-11-14 18:09:02 +053013094
13095 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13096
13097 if ( NULL == pTdlsPeer ) {
13098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13099 " peer not exsting",
13100 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013101 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013102 }
13103 else {
13104 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13105 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13106 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013107
13108 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13109 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013110 break;
13111 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013112 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013113 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013114 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13116 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13117 __func__, MAC_ADDR_ARRAY(peer));
13118
13119 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13120 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13121
13122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13123 " %s TDLS External control and Implicit Trigger not enabled ",
13124 __func__);
13125 return -ENOTSUPP;
13126 }
13127
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013128 /* To cater the requirement of establishing the TDLS link
13129 * irrespective of the data traffic , get an entry of TDLS peer.
13130 */
13131 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13132 if (pTdlsPeer == NULL) {
13133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13134 "%s: peer " MAC_ADDRESS_STR " not existing",
13135 __func__, MAC_ADDR_ARRAY(peer));
13136 return -EINVAL;
13137 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013138
13139 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13140
13141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13142 " %s TDLS Add Force Peer Failed",
13143 __func__);
13144 return -EINVAL;
13145 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013146 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013147 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013148 case NL80211_TDLS_DISCOVERY_REQ:
13149 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13151 "%s: We don't support in-driver setup/teardown/discovery "
13152 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013153 return -ENOTSUPP;
13154 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13156 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013157 return -ENOTSUPP;
13158 }
13159 return 0;
13160}
Chilam NG571c65a2013-01-19 12:27:36 +053013161
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013162static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13163 u8 *peer, enum nl80211_tdls_operation oper)
13164{
13165 int ret;
13166
13167 vos_ssr_protect(__func__);
13168 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13169 vos_ssr_unprotect(__func__);
13170
13171 return ret;
13172}
13173
Chilam NG571c65a2013-01-19 12:27:36 +053013174int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13175 struct net_device *dev, u8 *peer)
13176{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013177 hddLog(VOS_TRACE_LEVEL_INFO,
13178 "tdls send discover req: "MAC_ADDRESS_STR,
13179 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013180
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013181#if TDLS_MGMT_VERSION2
13182 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13183 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13184#else
Chilam NG571c65a2013-01-19 12:27:36 +053013185 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13186 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013187#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013188}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013189#endif
13190
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013191#ifdef WLAN_FEATURE_GTK_OFFLOAD
13192/*
13193 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13194 * Callback rountine called upon receiving response for
13195 * get offload info
13196 */
13197void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13198 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13199{
13200
13201 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013202 tANI_U8 tempReplayCounter[8];
13203 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013204
13205 ENTER();
13206
13207 if (NULL == pAdapter)
13208 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013210 "%s: HDD adapter is Null", __func__);
13211 return ;
13212 }
13213
13214 if (NULL == pGtkOffloadGetInfoRsp)
13215 {
13216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13217 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13218 return ;
13219 }
13220
13221 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13222 {
13223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13224 "%s: wlan Failed to get replay counter value",
13225 __func__);
13226 return ;
13227 }
13228
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013229 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13230 /* Update replay counter */
13231 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13232 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13233
13234 {
13235 /* changing from little to big endian since supplicant
13236 * works on big endian format
13237 */
13238 int i;
13239 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13240
13241 for (i = 0; i < 8; i++)
13242 {
13243 tempReplayCounter[7-i] = (tANI_U8)p[i];
13244 }
13245 }
13246
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013247 /* Update replay counter to NL */
13248 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013249 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013250}
13251
13252/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013253 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013254 * This function is used to offload GTK rekeying job to the firmware.
13255 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013256int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013257 struct cfg80211_gtk_rekey_data *data)
13258{
13259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13260 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13261 hdd_station_ctx_t *pHddStaCtx;
13262 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013263 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013264 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013265 eHalStatus status = eHAL_STATUS_FAILURE;
13266
13267 ENTER();
13268
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013269
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013270 if (NULL == pAdapter)
13271 {
Sushant Kaushik10728722014-05-14 16:20:25 +053013272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013273 "%s: HDD adapter is Null", __func__);
13274 return -ENODEV;
13275 }
13276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13278 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13279 pAdapter->sessionId, pAdapter->device_mode));
13280
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013281 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013282
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013283 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013284 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13286 "%s: HDD context is not valid", __func__);
13287 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013288 }
13289
13290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13291 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13292 if (NULL == hHal)
13293 {
13294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13295 "%s: HAL context is Null!!!", __func__);
13296 return -EAGAIN;
13297 }
13298
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013299 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13300 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13301 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13302 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013303 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013304 {
13305 /* changing from big to little endian since driver
13306 * works on little endian format
13307 */
13308 tANI_U8 *p =
13309 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13310 int i;
13311
13312 for (i = 0; i < 8; i++)
13313 {
13314 p[7-i] = data->replay_ctr[i];
13315 }
13316 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013317
13318 if (TRUE == pHddCtx->hdd_wlan_suspended)
13319 {
13320 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013321 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13322 sizeof (tSirGtkOffloadParams));
13323 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013324 pAdapter->sessionId);
13325
13326 if (eHAL_STATUS_SUCCESS != status)
13327 {
13328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13329 "%s: sme_SetGTKOffload failed, returned %d",
13330 __func__, status);
13331 return status;
13332 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13334 "%s: sme_SetGTKOffload successfull", __func__);
13335 }
13336 else
13337 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13339 "%s: wlan not suspended GTKOffload request is stored",
13340 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013341 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013342
13343 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013344}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013345
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013346int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13347 struct cfg80211_gtk_rekey_data *data)
13348{
13349 int ret;
13350
13351 vos_ssr_protect(__func__);
13352 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13353 vos_ssr_unprotect(__func__);
13354
13355 return ret;
13356}
13357#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013358/*
13359 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13360 * This function is used to set access control policy
13361 */
13362static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13363 struct net_device *dev, const struct cfg80211_acl_data *params)
13364{
13365 int i;
13366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13367 hdd_hostapd_state_t *pHostapdState;
13368 tsap_Config_t *pConfig;
13369 v_CONTEXT_t pVosContext = NULL;
13370 hdd_context_t *pHddCtx;
13371 int status;
13372
13373 ENTER();
13374
13375 if (NULL == pAdapter)
13376 {
13377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13378 "%s: HDD adapter is Null", __func__);
13379 return -ENODEV;
13380 }
13381
13382 if (NULL == params)
13383 {
13384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13385 "%s: params is Null", __func__);
13386 return -EINVAL;
13387 }
13388
13389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13390 status = wlan_hdd_validate_context(pHddCtx);
13391
13392 if (0 != status)
13393 {
13394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13395 "%s: HDD context is not valid", __func__);
13396 return status;
13397 }
13398
13399 pVosContext = pHddCtx->pvosContext;
13400 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13401
13402 if (NULL == pHostapdState)
13403 {
13404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13405 "%s: pHostapdState is Null", __func__);
13406 return -EINVAL;
13407 }
13408
13409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13410 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13411
13412 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13413 {
13414 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13415
13416 /* default value */
13417 pConfig->num_accept_mac = 0;
13418 pConfig->num_deny_mac = 0;
13419
13420 /**
13421 * access control policy
13422 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13423 * listed in hostapd.deny file.
13424 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13425 * listed in hostapd.accept file.
13426 */
13427 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13428 {
13429 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13430 }
13431 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13432 {
13433 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13434 }
13435 else
13436 {
13437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13438 "%s:Acl Policy : %d is not supported",
13439 __func__, params->acl_policy);
13440 return -ENOTSUPP;
13441 }
13442
13443 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13444 {
13445 pConfig->num_accept_mac = params->n_acl_entries;
13446 for (i = 0; i < params->n_acl_entries; i++)
13447 {
13448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13449 "** Add ACL MAC entry %i in WhiletList :"
13450 MAC_ADDRESS_STR, i,
13451 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13452
13453 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13454 sizeof(qcmacaddr));
13455 }
13456 }
13457 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13458 {
13459 pConfig->num_deny_mac = params->n_acl_entries;
13460 for (i = 0; i < params->n_acl_entries; i++)
13461 {
13462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13463 "** Add ACL MAC entry %i in BlackList :"
13464 MAC_ADDRESS_STR, i,
13465 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13466
13467 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13468 sizeof(qcmacaddr));
13469 }
13470 }
13471
13472 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13473 {
13474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13475 "%s: SAP Set Mac Acl fail", __func__);
13476 return -EINVAL;
13477 }
13478 }
13479 else
13480 {
13481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013482 "%s: Invalid device_mode = %s (%d)",
13483 __func__, hdd_device_modetoString(pAdapter->device_mode),
13484 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013485 return -EINVAL;
13486 }
13487
13488 return 0;
13489}
13490
Leo Chang9056f462013-08-01 19:21:11 -070013491#ifdef WLAN_NL80211_TESTMODE
13492#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013493void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013494(
13495 void *pAdapter,
13496 void *indCont
13497)
13498{
Leo Changd9df8aa2013-09-26 13:32:26 -070013499 tSirLPHBInd *lphbInd;
13500 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013501 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013502
13503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013504 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013505
c_hpothu73f35e62014-04-18 13:40:08 +053013506 if (pAdapter == NULL)
13507 {
13508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13509 "%s: pAdapter is NULL\n",__func__);
13510 return;
13511 }
13512
Leo Chang9056f462013-08-01 19:21:11 -070013513 if (NULL == indCont)
13514 {
13515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013516 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013517 return;
13518 }
13519
c_hpothu73f35e62014-04-18 13:40:08 +053013520 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013521 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013522 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013523 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013524 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013525 GFP_ATOMIC);
13526 if (!skb)
13527 {
13528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13529 "LPHB timeout, NL buffer alloc fail");
13530 return;
13531 }
13532
Leo Changac3ba772013-10-07 09:47:04 -070013533 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013534 {
13535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13536 "WLAN_HDD_TM_ATTR_CMD put fail");
13537 goto nla_put_failure;
13538 }
Leo Changac3ba772013-10-07 09:47:04 -070013539 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013540 {
13541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13542 "WLAN_HDD_TM_ATTR_TYPE put fail");
13543 goto nla_put_failure;
13544 }
Leo Changac3ba772013-10-07 09:47:04 -070013545 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013546 sizeof(tSirLPHBInd), lphbInd))
13547 {
13548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13549 "WLAN_HDD_TM_ATTR_DATA put fail");
13550 goto nla_put_failure;
13551 }
Leo Chang9056f462013-08-01 19:21:11 -070013552 cfg80211_testmode_event(skb, GFP_ATOMIC);
13553 return;
13554
13555nla_put_failure:
13556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13557 "NLA Put fail");
13558 kfree_skb(skb);
13559
13560 return;
13561}
13562#endif /* FEATURE_WLAN_LPHB */
13563
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013564static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013565{
13566 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13567 int err = 0;
13568#ifdef FEATURE_WLAN_LPHB
13569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013570 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013571#endif /* FEATURE_WLAN_LPHB */
13572
13573 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13574 if (err)
13575 {
13576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13577 "%s Testmode INV ATTR", __func__);
13578 return err;
13579 }
13580
13581 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13582 {
13583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13584 "%s Testmode INV CMD", __func__);
13585 return -EINVAL;
13586 }
13587
13588 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13589 {
13590#ifdef FEATURE_WLAN_LPHB
13591 /* Low Power Heartbeat configuration request */
13592 case WLAN_HDD_TM_CMD_WLAN_HB:
13593 {
13594 int buf_len;
13595 void *buf;
13596 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013597 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013598
13599 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13600 {
13601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13602 "%s Testmode INV DATA", __func__);
13603 return -EINVAL;
13604 }
13605
13606 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13607 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013608
13609 hb_params_temp =(tSirLPHBReq *)buf;
13610 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13611 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13612 return -EINVAL;
13613
Leo Chang9056f462013-08-01 19:21:11 -070013614 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13615 if (NULL == hb_params)
13616 {
13617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13618 "%s Request Buffer Alloc Fail", __func__);
13619 return -EINVAL;
13620 }
13621
13622 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013623 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13624 hb_params,
13625 wlan_hdd_cfg80211_lphb_ind_handler);
13626 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013627 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13629 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013630 vos_mem_free(hb_params);
13631 }
Leo Chang9056f462013-08-01 19:21:11 -070013632 return 0;
13633 }
13634#endif /* FEATURE_WLAN_LPHB */
13635 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13637 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013638 return -EOPNOTSUPP;
13639 }
13640
13641 return err;
13642}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013643
13644static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13645{
13646 int ret;
13647
13648 vos_ssr_protect(__func__);
13649 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13650 vos_ssr_unprotect(__func__);
13651
13652 return ret;
13653}
Leo Chang9056f462013-08-01 19:21:11 -070013654#endif /* CONFIG_NL80211_TESTMODE */
13655
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013656static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013657 struct net_device *dev,
13658 int idx, struct survey_info *survey)
13659{
13660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13661 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013662 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013663 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013664 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013665 v_S7_t snr,rssi;
13666 int status, i, j, filled = 0;
13667
13668 ENTER();
13669
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013670 if (NULL == pAdapter)
13671 {
13672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13673 "%s: HDD adapter is Null", __func__);
13674 return -ENODEV;
13675 }
13676
13677 if (NULL == wiphy)
13678 {
13679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13680 "%s: wiphy is Null", __func__);
13681 return -ENODEV;
13682 }
13683
13684 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13685 status = wlan_hdd_validate_context(pHddCtx);
13686
13687 if (0 != status)
13688 {
13689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13690 "%s: HDD context is not valid", __func__);
13691 return status;
13692 }
13693
Mihir Sheted9072e02013-08-21 17:02:29 +053013694 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13695
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013696 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013697 0 != pAdapter->survey_idx ||
13698 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013699 {
13700 /* The survey dump ops when implemented completely is expected to
13701 * return a survey of all channels and the ops is called by the
13702 * kernel with incremental values of the argument 'idx' till it
13703 * returns -ENONET. But we can only support the survey for the
13704 * operating channel for now. survey_idx is used to track
13705 * that the ops is called only once and then return -ENONET for
13706 * the next iteration
13707 */
13708 pAdapter->survey_idx = 0;
13709 return -ENONET;
13710 }
13711
13712 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13713
13714 wlan_hdd_get_snr(pAdapter, &snr);
13715 wlan_hdd_get_rssi(pAdapter, &rssi);
13716
13717 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13718 hdd_wlan_get_freq(channel, &freq);
13719
13720
13721 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13722 {
13723 if (NULL == wiphy->bands[i])
13724 {
13725 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13726 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13727 continue;
13728 }
13729
13730 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13731 {
13732 struct ieee80211_supported_band *band = wiphy->bands[i];
13733
13734 if (band->channels[j].center_freq == (v_U16_t)freq)
13735 {
13736 survey->channel = &band->channels[j];
13737 /* The Rx BDs contain SNR values in dB for the received frames
13738 * while the supplicant expects noise. So we calculate and
13739 * return the value of noise (dBm)
13740 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13741 */
13742 survey->noise = rssi - snr;
13743 survey->filled = SURVEY_INFO_NOISE_DBM;
13744 filled = 1;
13745 }
13746 }
13747 }
13748
13749 if (filled)
13750 pAdapter->survey_idx = 1;
13751 else
13752 {
13753 pAdapter->survey_idx = 0;
13754 return -ENONET;
13755 }
13756
13757 return 0;
13758}
13759
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013760static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13761 struct net_device *dev,
13762 int idx, struct survey_info *survey)
13763{
13764 int ret;
13765
13766 vos_ssr_protect(__func__);
13767 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13768 vos_ssr_unprotect(__func__);
13769
13770 return ret;
13771}
13772
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013773/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013774 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013775 * this is called when cfg80211 driver resume
13776 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13777 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013778int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013779{
13780 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13781 hdd_adapter_t *pAdapter;
13782 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13783 VOS_STATUS status = VOS_STATUS_SUCCESS;
13784
13785 ENTER();
13786
13787 if ( NULL == pHddCtx )
13788 {
13789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13790 "%s: HddCtx validation failed", __func__);
13791 return 0;
13792 }
13793
13794 if (pHddCtx->isLogpInProgress)
13795 {
13796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13797 "%s: LOGP in Progress. Ignore!!!", __func__);
13798 return 0;
13799 }
13800
Mihir Shete18156292014-03-11 15:38:30 +053013801 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013802 {
13803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13804 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13805 return 0;
13806 }
13807
13808 spin_lock(&pHddCtx->schedScan_lock);
13809 pHddCtx->isWiphySuspended = FALSE;
13810 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13811 {
13812 spin_unlock(&pHddCtx->schedScan_lock);
13813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13814 "%s: Return resume is not due to PNO indication", __func__);
13815 return 0;
13816 }
13817 // Reset flag to avoid updatating cfg80211 data old results again
13818 pHddCtx->isSchedScanUpdatePending = FALSE;
13819 spin_unlock(&pHddCtx->schedScan_lock);
13820
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013821
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013822 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13823
13824 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13825 {
13826 pAdapter = pAdapterNode->pAdapter;
13827 if ( (NULL != pAdapter) &&
13828 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13829 {
13830 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013831 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13833 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013834 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013835 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013836 {
13837 /* Acquire wakelock to handle the case where APP's tries to
13838 * suspend immediately after updating the scan results. Whis
13839 * results in app's is in suspended state and not able to
13840 * process the connect request to AP
13841 */
13842 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013843 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013844 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013845
13846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13847 "%s : cfg80211 scan result database updated", __func__);
13848
13849 return 0;
13850
13851 }
13852 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13853 pAdapterNode = pNext;
13854 }
13855
13856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13857 "%s: Failed to find Adapter", __func__);
13858 return 0;
13859}
13860
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013861int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13862{
13863 int ret;
13864
13865 vos_ssr_protect(__func__);
13866 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13867 vos_ssr_unprotect(__func__);
13868
13869 return ret;
13870}
13871
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013872/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013873 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013874 * this is called when cfg80211 driver suspends
13875 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013876int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013877 struct cfg80211_wowlan *wow)
13878{
13879 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13880
13881 ENTER();
13882 if (NULL == pHddCtx)
13883 {
13884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13885 "%s: HddCtx validation failed", __func__);
13886 return 0;
13887 }
13888
13889 pHddCtx->isWiphySuspended = TRUE;
13890
13891 EXIT();
13892
13893 return 0;
13894}
13895
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013896int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13897 struct cfg80211_wowlan *wow)
13898{
13899 int ret;
13900
13901 vos_ssr_protect(__func__);
13902 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13903 vos_ssr_unprotect(__func__);
13904
13905 return ret;
13906}
Jeff Johnson295189b2012-06-20 16:38:30 -070013907/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013908static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013909{
13910 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13911 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13912 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13913 .change_station = wlan_hdd_change_station,
13914#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13915 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13916 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13917 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013918#else
13919 .start_ap = wlan_hdd_cfg80211_start_ap,
13920 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13921 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013922#endif
13923 .change_bss = wlan_hdd_cfg80211_change_bss,
13924 .add_key = wlan_hdd_cfg80211_add_key,
13925 .get_key = wlan_hdd_cfg80211_get_key,
13926 .del_key = wlan_hdd_cfg80211_del_key,
13927 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013928#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 .scan = wlan_hdd_cfg80211_scan,
13932 .connect = wlan_hdd_cfg80211_connect,
13933 .disconnect = wlan_hdd_cfg80211_disconnect,
13934 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13935 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13936 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13937 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13938 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13940 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013941 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13943 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13944 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13945 .set_txq_params = wlan_hdd_set_txq_params,
13946#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 .get_station = wlan_hdd_cfg80211_get_station,
13948 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13949 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013950 .add_station = wlan_hdd_cfg80211_add_station,
13951#ifdef FEATURE_WLAN_LFR
13952 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13953 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13954 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13955#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013956#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13957 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13958#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013959#ifdef FEATURE_WLAN_TDLS
13960 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13961 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13962#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013963#ifdef WLAN_FEATURE_GTK_OFFLOAD
13964 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13965#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013966#ifdef FEATURE_WLAN_SCAN_PNO
13967 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13968 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13969#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013970 .resume = wlan_hdd_cfg80211_resume_wlan,
13971 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013972 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013973#ifdef WLAN_NL80211_TESTMODE
13974 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13975#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013976 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013977};
13978