blob: 2d14f63a20f337fa1013527a6143caf3e4461540 [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,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2801 pData->requestId) ||
2802 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2804 pData->status)) {
2805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2806 goto nla_put_failure;
2807 }
2808
2809 cfg80211_vendor_event(skb, GFP_KERNEL);
2810 return;
2811
2812nla_put_failure:
2813 kfree_skb(skb);
2814 return;
2815}
2816
2817void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2818 void *pMsg)
2819{
2820 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2821
2822 if (wlan_hdd_validate_context(pHddCtx)) {
2823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2824 return;
2825 }
2826
2827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2828
2829
2830 switch(evType) {
2831 case SIR_HAL_EXTSCAN_START_RSP:
2832 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2833 break;
2834
2835 case SIR_HAL_EXTSCAN_STOP_RSP:
2836 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2837 break;
2838 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2839 /* There is no need to send this response to upper layer
2840 Just log the message */
2841 hddLog(VOS_TRACE_LEVEL_INFO,
2842 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2843 break;
2844 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2845 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2846 break;
2847
2848 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2849 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2850 break;
2851
2852 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2853 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2854 break;
2855
2856 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2857 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2858 break;
2859 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2860 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2861 break;
2862 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2863 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2864 break;
2865 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2866 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2867 break;
2868 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2869 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2870 break;
2871 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2872 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2875 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2876 break;
2877 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2878 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2879 break;
2880 default:
2881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2882 break;
2883 }
2884}
2885
2886static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2887 struct wireless_dev *wdev,
2888 void *data, int dataLen)
2889{
2890 tpSirGetEXTScanCapabilitiesReqParams pReqMsg = NULL;
2891 struct net_device *dev = wdev->netdev;
2892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2893 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2894 struct nlattr
2895 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2896 eHalStatus status;
2897
2898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2899 status = wlan_hdd_validate_context(pHddCtx);
2900 if (0 != status)
2901 {
2902 hddLog(VOS_TRACE_LEVEL_ERROR,
2903 FL("HDD context is not valid"));
2904 return -EINVAL;
2905 }
2906 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2907 data, dataLen,
2908 wlan_hdd_extscan_config_policy)) {
2909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2910 return -EINVAL;
2911 }
2912
2913 /* Parse and fetch request Id */
2914 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2916 return -EINVAL;
2917 }
2918
2919 pReqMsg = (tpSirGetEXTScanCapabilitiesReqParams)
2920 vos_mem_malloc(sizeof(*pReqMsg));
2921 if (!pReqMsg) {
2922 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2923 return -ENOMEM;
2924 }
2925
2926 pReqMsg->requestId = nla_get_u32(
2927 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2929
2930 pReqMsg->sessionId = pAdapter->sessionId;
2931 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2932
2933 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, pReqMsg);
2934 if (!HAL_STATUS_SUCCESS(status)) {
2935 hddLog(VOS_TRACE_LEVEL_ERROR,
2936 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
2937 vos_mem_free(pReqMsg);
2938 return -EINVAL;
2939 }
2940
2941 return 0;
2942}
2943
2944
2945static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2946 struct wireless_dev *wdev,
2947 void *data, int dataLen)
2948{
2949 tpSirEXTScanGetCachedResultsReqParams pReqMsg = NULL;
2950 struct net_device *dev = wdev->netdev;
2951 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2952 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2953 struct nlattr
2954 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2955 eHalStatus status;
2956
2957 status = wlan_hdd_validate_context(pHddCtx);
2958 if (0 != status)
2959 {
2960 hddLog(VOS_TRACE_LEVEL_ERROR,
2961 FL("HDD context is not valid"));
2962 return -EINVAL;
2963 }
2964 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2965 data, dataLen,
2966 wlan_hdd_extscan_config_policy)) {
2967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2968 return -EINVAL;
2969 }
2970 /* Parse and fetch request Id */
2971 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2973 return -EINVAL;
2974 }
2975 pReqMsg = (tpSirEXTScanGetCachedResultsReqParams)
2976 vos_mem_malloc(sizeof(*pReqMsg));
2977 if (!pReqMsg) {
2978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2979 return -ENOMEM;
2980 }
2981
2982 pReqMsg->requestId = nla_get_u32(
2983 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2984
2985 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2986
2987 pReqMsg->sessionId = pAdapter->sessionId;
2988 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2989
2990 /* Parse and fetch flush parameter */
2991 if (!tb
2992 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2993 {
2994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2995 goto failed;
2996 }
2997 pReqMsg->flush = nla_get_u8(
2998 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
2999
3000 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush);
3001
3002 status = sme_getCachedResults(pHddCtx->hHal, pReqMsg);
3003 if (!HAL_STATUS_SUCCESS(status)) {
3004 hddLog(VOS_TRACE_LEVEL_ERROR,
3005 FL("sme_getCachedResults failed(err=%d)"), status);
3006 vos_mem_free(pReqMsg);
3007 return -EINVAL;
3008 }
3009 return 0;
3010
3011failed:
3012 vos_mem_free(pReqMsg);
3013 return -EINVAL;
3014}
3015
3016static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3017 struct wireless_dev *wdev,
3018 void *data, int dataLen)
3019{
3020 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3021 struct net_device *dev = wdev->netdev;
3022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3023 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3024 struct nlattr
3025 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3026 struct nlattr
3027 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3028 struct nlattr *apTh;
3029 eHalStatus status;
3030 tANI_U8 i = 0;
3031 int rem;
3032
3033 status = wlan_hdd_validate_context(pHddCtx);
3034 if (0 != status)
3035 {
3036 hddLog(VOS_TRACE_LEVEL_ERROR,
3037 FL("HDD context is not valid"));
3038 return -EINVAL;
3039 }
3040 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3041 data, dataLen,
3042 wlan_hdd_extscan_config_policy)) {
3043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3044 return -EINVAL;
3045 }
3046
3047 /* Parse and fetch request Id */
3048 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3050 return -EINVAL;
3051 }
3052
3053 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3054 vos_mem_malloc(sizeof(*pReqMsg));
3055 if (!pReqMsg) {
3056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3057 return -ENOMEM;
3058 }
3059
3060 pReqMsg->requestId = nla_get_u32(
3061 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3062 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3063
3064 /* Parse and fetch number of APs */
3065 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3067 goto fail;
3068 }
3069
3070 pReqMsg->sessionId = pAdapter->sessionId;
3071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3072
3073 pReqMsg->numAp = nla_get_u32(
3074 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3076
3077 nla_for_each_nested(apTh,
3078 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3079 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3080 nla_data(apTh), nla_len(apTh),
3081 NULL)) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3083 goto fail;
3084 }
3085
3086 /* Parse and fetch MAC address */
3087 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3089 goto fail;
3090 }
3091 memcpy(pReqMsg->ap[i].bssid, nla_data(
3092 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3093 sizeof(tSirMacAddr));
3094 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3095
3096 /* Parse and fetch low RSSI */
3097 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3099 goto fail;
3100 }
3101 pReqMsg->ap[i].low = nla_get_s32(
3102 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3103 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3104
3105 /* Parse and fetch high RSSI */
3106 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3107 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3108 goto fail;
3109 }
3110 pReqMsg->ap[i].high = nla_get_s32(
3111 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3112 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3113 pReqMsg->ap[i].high);
3114
3115 /* Parse and fetch channel */
3116 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3118 goto fail;
3119 }
3120 pReqMsg->ap[i].channel = nla_get_u32(
3121 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3122 hddLog(VOS_TRACE_LEVEL_INFO,
3123 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3124 i++;
3125 }
3126 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3127 if (!HAL_STATUS_SUCCESS(status)) {
3128 hddLog(VOS_TRACE_LEVEL_ERROR,
3129 FL("sme_SetBssHotlist failed(err=%d)"), status);
3130 vos_mem_free(pReqMsg);
3131 return -EINVAL;
3132 }
3133
3134 return 0;
3135
3136fail:
3137 vos_mem_free(pReqMsg);
3138 return -EINVAL;
3139}
3140
3141static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3142 struct wireless_dev *wdev,
3143 void *data, int dataLen)
3144{
3145 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3146 struct net_device *dev = wdev->netdev;
3147 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3148 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3149 struct nlattr
3150 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3151 struct nlattr
3152 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3153 struct nlattr *apTh;
3154 eHalStatus status;
3155 int i = 0;
3156 int rem;
3157
3158 status = wlan_hdd_validate_context(pHddCtx);
3159 if (0 != status)
3160 {
3161 hddLog(VOS_TRACE_LEVEL_ERROR,
3162 FL("HDD context is not valid"));
3163 return -EINVAL;
3164 }
3165 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3166 data, dataLen,
3167 wlan_hdd_extscan_config_policy)) {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3169 return -EINVAL;
3170 }
3171
3172 /* Parse and fetch request Id */
3173 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3175 return -EINVAL;
3176 }
3177
3178 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
3179 vos_mem_malloc(sizeof(*pReqMsg));
3180 if (!pReqMsg) {
3181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3182 return -ENOMEM;
3183 }
3184
3185 pReqMsg->requestId = nla_get_u32(
3186 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3187 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3188
3189 /* Parse and fetch RSSI sample size */
3190 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3191 {
3192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3193 goto fail;
3194 }
3195 pReqMsg->rssiSampleSize = nla_get_u32(
3196 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3197 hddLog(VOS_TRACE_LEVEL_INFO,
3198 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3199
3200 /* Parse and fetch lost AP sample size */
3201 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3202 {
3203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3204 goto fail;
3205 }
3206 pReqMsg->lostApSampleSize = nla_get_u32(
3207 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3208 hddLog(VOS_TRACE_LEVEL_INFO,
3209 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3210 /* Parse and fetch minimum Breaching */
3211 if (!tb
3212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3214 goto fail;
3215 }
3216 pReqMsg->minBreaching = nla_get_u32(
3217 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3218 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3219
3220 /* Parse and fetch number of APs */
3221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3223 goto fail;
3224 }
3225 pReqMsg->numAp = nla_get_u32(
3226 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3228
3229 pReqMsg->sessionId = pAdapter->sessionId;
3230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3231
3232 nla_for_each_nested(apTh,
3233 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3234 if(nla_parse(tb2,
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3236 nla_data(apTh), nla_len(apTh),
3237 NULL)) {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3239 goto fail;
3240 }
3241
3242 /* Parse and fetch MAC address */
3243 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3245 goto fail;
3246 }
3247 memcpy(pReqMsg->ap[i].bssid, nla_data(
3248 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3249 sizeof(tSirMacAddr));
3250
3251 /* Parse and fetch low RSSI */
3252 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3254 goto fail;
3255 }
3256 pReqMsg->ap[i].low = nla_get_s32(
3257 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3258 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3259
3260 /* Parse and fetch high RSSI */
3261 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3263 goto fail;
3264 }
3265 pReqMsg->ap[i].high = nla_get_s32(
3266 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3267 hddLog(VOS_TRACE_LEVEL_INFO,
3268 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3269
3270 /* Parse and fetch channel */
3271 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3273 goto fail;
3274 }
3275 pReqMsg->ap[i].channel = nla_get_u32(
3276 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3277 hddLog(VOS_TRACE_LEVEL_INFO,
3278 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3279 i++;
3280 }
3281
3282 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3283 if (!HAL_STATUS_SUCCESS(status)) {
3284 hddLog(VOS_TRACE_LEVEL_ERROR,
3285 FL("sme_SetSignificantChange failed(err=%d)"), status);
3286 vos_mem_free(pReqMsg);
3287 return -EINVAL;
3288 }
3289
3290 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3291 return 0;
3292
3293fail:
3294 vos_mem_free(pReqMsg);
3295 return -EINVAL;
3296}
3297
3298static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3299 struct wireless_dev *wdev,
3300 void *data, int dataLen)
3301{
3302 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3303 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3304 tANI_U8 numChannels = 0;
3305 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3306 tANI_U32 requestId;
3307 tWifiBand wifiBand;
3308 eHalStatus status;
3309 struct sk_buff *replySkb;
3310 tANI_U8 i;
3311
3312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3313 status = wlan_hdd_validate_context(pHddCtx);
3314 if (0 != status)
3315 {
3316 hddLog(VOS_TRACE_LEVEL_ERROR,
3317 FL("HDD context is not valid"));
3318 return -EINVAL;
3319 }
3320 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3321 data, dataLen,
3322 wlan_hdd_extscan_config_policy)) {
3323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3324 return -EINVAL;
3325 }
3326
3327 /* Parse and fetch request Id */
3328 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3330 return -EINVAL;
3331 }
3332 requestId = nla_get_u32(
3333 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3334 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3335
3336 /* Parse and fetch wifi band */
3337 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3338 {
3339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3340 return -EINVAL;
3341 }
3342 wifiBand = nla_get_u32(
3343 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3344 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3345
3346 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3347 wifiBand, ChannelList,
3348 &numChannels);
3349 if (eHAL_STATUS_SUCCESS != status) {
3350 hddLog(VOS_TRACE_LEVEL_ERROR,
3351 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3352 return -EINVAL;
3353 }
3354 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3355 for (i = 0; i < numChannels; i++)
3356 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3357
3358 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3359 sizeof(u32) * numChannels +
3360 NLMSG_HDRLEN);
3361
3362 if (!replySkb) {
3363 hddLog(VOS_TRACE_LEVEL_ERROR,
3364 FL("valid channels: buffer alloc fail"));
3365 return -EINVAL;
3366 }
3367 if (nla_put_u32(replySkb,
3368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3369 numChannels) ||
3370 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3371 sizeof(u32) * numChannels, ChannelList)) {
3372
3373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3374 kfree_skb(replySkb);
3375 return -EINVAL;
3376 }
3377
3378 return cfg80211_vendor_cmd_reply(replySkb);
3379}
3380
3381static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3382 struct wireless_dev *wdev,
3383 void *data, int dataLen)
3384{
3385 tpSirEXTScanStartReqParams pReqMsg = NULL;
3386 struct net_device *dev = wdev->netdev;
3387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3388 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3389 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3390 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3391 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3392 struct nlattr *buckets;
3393 struct nlattr *channels;
3394 int rem1;
3395 int rem2;
3396 eHalStatus status;
3397 tANI_U8 bktIndex;
3398 tANI_U32 i = 0, j = 0;
3399
3400 status = wlan_hdd_validate_context(pHddCtx);
3401 if (0 != status)
3402 {
3403 hddLog(VOS_TRACE_LEVEL_ERROR,
3404 FL("HDD context is not valid"));
3405 return -EINVAL;
3406 }
3407 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3408 data, dataLen,
3409 wlan_hdd_extscan_config_policy)) {
3410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3411 return -EINVAL;
3412 }
3413
3414 /* Parse and fetch request Id */
3415 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3417 return -EINVAL;
3418 }
3419
3420 pReqMsg = (tpSirEXTScanStartReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3421 if (!pReqMsg) {
3422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3423 return -ENOMEM;
3424 }
3425
3426 pReqMsg->requestId = nla_get_u32(
3427 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3429
3430 pReqMsg->sessionId = pAdapter->sessionId;
3431 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3432
3433 /* Parse and fetch base period */
3434 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3436 goto fail;
3437 }
3438 pReqMsg->basePeriod = nla_get_u32(
3439 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3440 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3441 pReqMsg->basePeriod);
3442
3443 /* Parse and fetch max AP per scan */
3444 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3446 goto fail;
3447 }
3448 pReqMsg->maxAPperScan = nla_get_u32(
3449 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3450 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3451 pReqMsg->maxAPperScan);
3452
3453 /* Parse and fetch report threshold */
3454 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3456 goto fail;
3457 }
3458 pReqMsg->reportThreshold = nla_get_u8(
3459 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3461 pReqMsg->reportThreshold);
3462
3463 /* Parse and fetch number of buckets */
3464 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3466 goto fail;
3467 }
3468 pReqMsg->numBuckets = nla_get_u8(
3469 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3470 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3471 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3472 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3473 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3474 }
3475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3476 pReqMsg->numBuckets);
3477 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3479 goto fail;
3480 }
3481
3482 nla_for_each_nested(buckets,
3483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3484 if(nla_parse(bucket,
3485 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3486 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3488 goto fail;
3489 }
3490
3491 /* Parse and fetch bucket spec */
3492 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3494 goto fail;
3495 }
3496 bktIndex = nla_get_u8(
3497 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3499 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3500
3501 /* Parse and fetch wifi band */
3502 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3504 goto fail;
3505 }
3506 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3507 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3508 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3509 pReqMsg->buckets[bktIndex].band);
3510
3511 /* Parse and fetch period */
3512 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3514 goto fail;
3515 }
3516 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3517 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3518 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3519 pReqMsg->buckets[bktIndex].period);
3520
3521 /* Parse and fetch report events */
3522 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3524 goto fail;
3525 }
3526 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3527 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3528 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3529 pReqMsg->buckets[bktIndex].reportEvents);
3530
3531 /* Parse and fetch number of channels */
3532 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3534 goto fail;
3535 }
3536 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3537 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3538 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3539 pReqMsg->buckets[bktIndex].numChannels);
3540
3541 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3543 goto fail;
3544 }
3545
3546 j = 0;
3547 nla_for_each_nested(channels,
3548 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3549 if(nla_parse(channel,
3550 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3551 nla_data(channels), nla_len(channels),
3552 NULL)) { //wlan_hdd_extscan_config_policy here
3553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3554 goto fail;
3555 }
3556
3557 /* Parse and fetch channel */
3558 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3560 goto fail;
3561 }
3562 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3563 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3564 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3565 pReqMsg->buckets[bktIndex].channels[j].channel);
3566
3567 /* Parse and fetch dwell time */
3568 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3570 goto fail;
3571 }
3572 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3573 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3574 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3575 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3576
3577 /* Parse and fetch channel spec passive */
3578 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR,
3580 FL("attr channel spec passive failed"));
3581 goto fail;
3582 }
3583 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3584 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3586 pReqMsg->buckets[bktIndex].channels[j].passive);
3587 j++;
3588 }
3589 i++;
3590 }
3591 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3592 if (!HAL_STATUS_SUCCESS(status)) {
3593 hddLog(VOS_TRACE_LEVEL_ERROR,
3594 FL("sme_EXTScanStart failed(err=%d)"), status);
3595 vos_mem_free(pReqMsg);
3596 return -EINVAL;
3597 }
3598
3599 return 0;
3600
3601fail:
3602 vos_mem_free(pReqMsg);
3603 return -EINVAL;
3604}
3605
3606static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3607 struct wireless_dev *wdev,
3608 void *data, int dataLen)
3609{
3610 tpSirEXTScanStopReqParams pReqMsg = NULL;
3611 struct net_device *dev = wdev->netdev;
3612 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3613 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3614 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3615 eHalStatus status;
3616
3617 status = wlan_hdd_validate_context(pHddCtx);
3618 if (0 != status)
3619 {
3620 hddLog(VOS_TRACE_LEVEL_ERROR,
3621 FL("HDD context is not valid"));
3622 return -EINVAL;
3623 }
3624 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3625 data, dataLen,
3626 wlan_hdd_extscan_config_policy)) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3628 return -EINVAL;
3629 }
3630
3631 /* Parse and fetch request Id */
3632 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3634 return -EINVAL;
3635 }
3636
3637 pReqMsg = (tpSirEXTScanStopReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3638 if (!pReqMsg) {
3639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3640 return -ENOMEM;
3641 }
3642
3643 pReqMsg->requestId = nla_get_u32(
3644 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3646
3647 pReqMsg->sessionId = pAdapter->sessionId;
3648 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3649
3650 status = sme_EXTScanStop(pHddCtx->hHal, pReqMsg);
3651 if (!HAL_STATUS_SUCCESS(status)) {
3652 hddLog(VOS_TRACE_LEVEL_ERROR,
3653 FL("sme_EXTScanStop failed(err=%d)"), status);
3654 vos_mem_free(pReqMsg);
3655 return -EINVAL;
3656 }
3657
3658 return 0;
3659}
3660
3661static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3662 struct wireless_dev *wdev,
3663 void *data, int dataLen)
3664{
3665 tpSirEXTScanResetBssidHotlistReqParams pReqMsg = NULL;
3666 struct net_device *dev = wdev->netdev;
3667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3668 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3670 eHalStatus status;
3671
3672 status = wlan_hdd_validate_context(pHddCtx);
3673 if (0 != status)
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR,
3676 FL("HDD context is not valid"));
3677 return -EINVAL;
3678 }
3679 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3680 data, dataLen,
3681 wlan_hdd_extscan_config_policy)) {
3682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3683 return -EINVAL;
3684 }
3685
3686 /* Parse and fetch request Id */
3687 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3689 return -EINVAL;
3690 }
3691
3692 pReqMsg = (tpSirEXTScanResetBssidHotlistReqParams)
3693 vos_mem_malloc(sizeof(*pReqMsg));
3694 if (!pReqMsg) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3696 return -ENOMEM;
3697 }
3698
3699 pReqMsg->requestId = nla_get_u32(
3700 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3702
3703 pReqMsg->sessionId = pAdapter->sessionId;
3704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3705
3706 status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
3707 if (!HAL_STATUS_SUCCESS(status)) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR,
3709 FL("sme_ResetBssHotlist failed(err=%d)"), status);
3710 vos_mem_free(pReqMsg);
3711 return -EINVAL;
3712 }
3713
3714 return 0;
3715}
3716
3717static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3718 struct wiphy *wiphy,
3719 struct wireless_dev *wdev,
3720 void *data, int dataLen)
3721{
3722 tpSirEXTScanResetSignificantChangeReqParams pReqMsg = NULL;
3723 struct net_device *dev = wdev->netdev;
3724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3726 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3727 eHalStatus status;
3728
3729 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3730 status = wlan_hdd_validate_context(pHddCtx);
3731 if (0 != status)
3732 {
3733 hddLog(VOS_TRACE_LEVEL_ERROR,
3734 FL("HDD context is not valid"));
3735 return -EINVAL;
3736 }
3737 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3738 data, dataLen,
3739 wlan_hdd_extscan_config_policy)) {
3740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3741 return -EINVAL;
3742 }
3743
3744 /* Parse and fetch request Id */
3745 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3747 return -EINVAL;
3748 }
3749
3750 pReqMsg = (tpSirEXTScanResetSignificantChangeReqParams)
3751 vos_mem_malloc(sizeof(*pReqMsg));
3752 if (!pReqMsg) {
3753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3754 return -ENOMEM;
3755 }
3756
3757 pReqMsg->requestId = nla_get_u32(
3758 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3760
3761 pReqMsg->sessionId = pAdapter->sessionId;
3762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3763
3764 status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
3765 if (!HAL_STATUS_SUCCESS(status)) {
3766 hddLog(VOS_TRACE_LEVEL_ERROR,
3767 FL("sme_ResetSignificantChange failed(err=%d)"), status);
3768 vos_mem_free(pReqMsg);
3769 return -EINVAL;
3770 }
3771
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3773 return 0;
3774}
3775
3776#endif /* WLAN_FEATURE_EXTSCAN */
3777
Sunil Duttc69bccb2014-05-26 21:30:20 +05303778const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3779{
3780#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3781 {
3782 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3783 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3784 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3785 WIPHY_VENDOR_CMD_NEED_NETDEV |
3786 WIPHY_VENDOR_CMD_NEED_RUNNING,
3787 .doit = wlan_hdd_cfg80211_ll_stats_clear
3788 },
3789
3790 {
3791 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3792 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3793 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3794 WIPHY_VENDOR_CMD_NEED_NETDEV |
3795 WIPHY_VENDOR_CMD_NEED_RUNNING,
3796 .doit = wlan_hdd_cfg80211_ll_stats_set
3797 },
3798
3799 {
3800 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3801 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3802 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3803 WIPHY_VENDOR_CMD_NEED_NETDEV |
3804 WIPHY_VENDOR_CMD_NEED_RUNNING,
3805 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303806 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303807#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808#ifdef WLAN_FEATURE_EXTSCAN
3809 {
3810 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3811 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3812 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3813 WIPHY_VENDOR_CMD_NEED_NETDEV |
3814 WIPHY_VENDOR_CMD_NEED_RUNNING,
3815 .doit = wlan_hdd_cfg80211_extscan_start
3816 },
3817 {
3818 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3819 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3820 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3821 WIPHY_VENDOR_CMD_NEED_NETDEV |
3822 WIPHY_VENDOR_CMD_NEED_RUNNING,
3823 .doit = wlan_hdd_cfg80211_extscan_stop
3824 },
3825 {
3826 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3827 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3828 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3829 WIPHY_VENDOR_CMD_NEED_NETDEV,
3830 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3831 },
3832 {
3833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3836 WIPHY_VENDOR_CMD_NEED_NETDEV |
3837 WIPHY_VENDOR_CMD_NEED_RUNNING,
3838 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3839 },
3840 {
3841 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3842 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3843 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3844 WIPHY_VENDOR_CMD_NEED_NETDEV |
3845 WIPHY_VENDOR_CMD_NEED_RUNNING,
3846 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3847 },
3848 {
3849 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3850 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3851 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3852 WIPHY_VENDOR_CMD_NEED_NETDEV |
3853 WIPHY_VENDOR_CMD_NEED_RUNNING,
3854 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3855 },
3856 {
3857 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3858 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3859 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3860 WIPHY_VENDOR_CMD_NEED_NETDEV |
3861 WIPHY_VENDOR_CMD_NEED_RUNNING,
3862 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3863 },
3864 {
3865 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3866 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3867 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3868 WIPHY_VENDOR_CMD_NEED_NETDEV |
3869 WIPHY_VENDOR_CMD_NEED_RUNNING,
3870 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3871 },
3872 {
3873 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3874 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3875 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3876 WIPHY_VENDOR_CMD_NEED_NETDEV |
3877 WIPHY_VENDOR_CMD_NEED_RUNNING,
3878 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3879 },
3880#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303881};
3882
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003883/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303884static const
3885struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003886{
3887#ifdef FEATURE_WLAN_CH_AVOID
3888 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303889 .vendor_id = QCA_NL80211_VENDOR_ID,
3890 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003891 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303892#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3893#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3894 {
3895 /* Index = 1*/
3896 .vendor_id = QCA_NL80211_VENDOR_ID,
3897 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3898 },
3899 {
3900 /* Index = 2*/
3901 .vendor_id = QCA_NL80211_VENDOR_ID,
3902 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3903 },
3904 {
3905 /* Index = 3*/
3906 .vendor_id = QCA_NL80211_VENDOR_ID,
3907 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3908 },
3909 {
3910 /* Index = 4*/
3911 .vendor_id = QCA_NL80211_VENDOR_ID,
3912 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3913 },
3914 {
3915 /* Index = 5*/
3916 .vendor_id = QCA_NL80211_VENDOR_ID,
3917 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3918 },
3919 {
3920 /* Index = 6*/
3921 .vendor_id = QCA_NL80211_VENDOR_ID,
3922 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3923 },
3924#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925#ifdef WLAN_FEATURE_EXTSCAN
3926 {
3927 .vendor_id = QCA_NL80211_VENDOR_ID,
3928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3929 },
3930 {
3931 .vendor_id = QCA_NL80211_VENDOR_ID,
3932 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3933 },
3934 {
3935 .vendor_id = QCA_NL80211_VENDOR_ID,
3936 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3937 },
3938 {
3939 .vendor_id = QCA_NL80211_VENDOR_ID,
3940 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3941 },
3942 {
3943 .vendor_id = QCA_NL80211_VENDOR_ID,
3944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3945 },
3946 {
3947 .vendor_id = QCA_NL80211_VENDOR_ID,
3948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3949 },
3950 {
3951 .vendor_id = QCA_NL80211_VENDOR_ID,
3952 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
3953 },
3954 {
3955 .vendor_id = QCA_NL80211_VENDOR_ID,
3956 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
3957 },
3958 {
3959 .vendor_id = QCA_NL80211_VENDOR_ID,
3960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
3961 },
3962 {
3963 .vendor_id = QCA_NL80211_VENDOR_ID,
3964 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
3965 },
3966 {
3967 .vendor_id = QCA_NL80211_VENDOR_ID,
3968 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
3969 },
3970 {
3971 .vendor_id = QCA_NL80211_VENDOR_ID,
3972 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
3973 },
3974 {
3975 .vendor_id = QCA_NL80211_VENDOR_ID,
3976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
3977 },
3978#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303979
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003980};
3981
Jeff Johnson295189b2012-06-20 16:38:30 -07003982/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303983 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303984 * This function is called by hdd_wlan_startup()
3985 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303986 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303988struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07003989{
3990 struct wiphy *wiphy;
3991 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303992 /*
3993 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07003994 */
3995 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
3996
3997 if (!wiphy)
3998 {
3999 /* Print error and jump into err label and free the memory */
4000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4001 return NULL;
4002 }
4003
Sunil Duttc69bccb2014-05-26 21:30:20 +05304004
Jeff Johnson295189b2012-06-20 16:38:30 -07004005 return wiphy;
4006}
4007
4008/*
4009 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304010 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004011 * private ioctl to change the band value
4012 */
4013int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4014{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304015 int i, j;
4016 eNVChannelEnabledType channelEnabledState;
4017
Jeff Johnsone7245742012-09-05 17:12:55 -07004018 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304019
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304020 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004021 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304022
4023 if (NULL == wiphy->bands[i])
4024 {
4025 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4026 __func__, i);
4027 continue;
4028 }
4029
4030 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4031 {
4032 struct ieee80211_supported_band *band = wiphy->bands[i];
4033
4034 channelEnabledState = vos_nv_getChannelEnabledState(
4035 band->channels[j].hw_value);
4036
4037 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4038 {
4039 // Enable Social channels for P2P
4040 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4041 NV_CHANNEL_ENABLE == channelEnabledState)
4042 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4043 else
4044 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4045 continue;
4046 }
4047 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4048 {
4049 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4050 continue;
4051 }
4052
4053 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4054 NV_CHANNEL_INVALID == channelEnabledState)
4055 {
4056 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4057 }
4058 else if (NV_CHANNEL_DFS == channelEnabledState)
4059 {
4060 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4061 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4062 }
4063 else
4064 {
4065 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4066 |IEEE80211_CHAN_RADAR);
4067 }
4068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 }
4070 return 0;
4071}
4072/*
4073 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 * This function is called by hdd_wlan_startup()
4075 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 * This function is used to initialize and register wiphy structure.
4077 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304078int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004079 struct wiphy *wiphy,
4080 hdd_config_t *pCfg
4081 )
4082{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304083 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304084 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4085
Jeff Johnsone7245742012-09-05 17:12:55 -07004086 ENTER();
4087
Jeff Johnson295189b2012-06-20 16:38:30 -07004088 /* Now bind the underlying wlan device with wiphy */
4089 set_wiphy_dev(wiphy, dev);
4090
4091 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004092
Kiet Lam6c583332013-10-14 05:37:09 +05304093#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004094 /* the flag for the other case would be initialzed in
4095 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004096 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304097#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004098
Amar Singhalfddc28c2013-09-05 13:03:40 -07004099 /* This will disable updating of NL channels from passive to
4100 * active if a beacon is received on passive channel. */
4101 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004102
Amar Singhalfddc28c2013-09-05 13:03:40 -07004103
Amar Singhala49cbc52013-10-08 18:37:44 -07004104
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004106 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4107 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4108 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004109 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304110 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004111#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004112
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004113#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004114 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004115#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004116 || pCfg->isFastRoamIniFeatureEnabled
4117#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004118#ifdef FEATURE_WLAN_ESE
4119 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004120#endif
4121 )
4122 {
4123 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4124 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004125#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004126#ifdef FEATURE_WLAN_TDLS
4127 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4128 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4129#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304130#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304131 if (pCfg->configPNOScanSupport)
4132 {
4133 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4134 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4135 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4136 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4137 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304138#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004139
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004141 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4142 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004143 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004144 driver need to determine what to do with both
4145 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004146
4147 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004148#else
4149 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004150#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304152 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4153
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304154 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004155
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304156 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4157
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304159 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4162 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004163 | BIT(NL80211_IFTYPE_AP);
4164
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304165 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004166 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304167#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4168 if( pCfg->enableMCC )
4169 {
4170 /* Currently, supports up to two channels */
4171 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004172
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304173 if( !pCfg->allowMCCGODiffBI )
4174 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004175
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304176 }
4177 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4178 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004179#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304180 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004181
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 /* Before registering we need to update the ht capabilitied based
4183 * on ini values*/
4184 if( !pCfg->ShortGI20MhzEnable )
4185 {
4186 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4187 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4188 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4189 }
4190
4191 if( !pCfg->ShortGI40MhzEnable )
4192 {
4193 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4194 }
4195
4196 if( !pCfg->nChannelBondingMode5GHz )
4197 {
4198 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4199 }
4200
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304201 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304202 if (true == hdd_is_5g_supported(pHddCtx))
4203 {
4204 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4205 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304206
4207 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4208 {
4209
4210 if (NULL == wiphy->bands[i])
4211 {
4212 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4213 __func__, i);
4214 continue;
4215 }
4216
4217 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4218 {
4219 struct ieee80211_supported_band *band = wiphy->bands[i];
4220
4221 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4222 {
4223 // Enable social channels for P2P
4224 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4225 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4226 else
4227 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4228 continue;
4229 }
4230 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4231 {
4232 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4233 continue;
4234 }
4235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004236 }
4237 /*Initialise the supported cipher suite details*/
4238 wiphy->cipher_suites = hdd_cipher_suites;
4239 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4240
4241 /*signal strength in mBm (100*dBm) */
4242 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4243
4244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004245 wiphy->max_remain_on_channel_duration = 1000;
4246#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004247
Sunil Duttc69bccb2014-05-26 21:30:20 +05304248 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4249 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004250 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4251 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4252
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304253 EXIT();
4254 return 0;
4255}
4256
4257/* In this function we are registering wiphy. */
4258int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4259{
4260 ENTER();
4261 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 if (0 > wiphy_register(wiphy))
4263 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304264 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4266 return -EIO;
4267 }
4268
4269 EXIT();
4270 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304271}
Jeff Johnson295189b2012-06-20 16:38:30 -07004272
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304273/* In this function we are updating channel list when,
4274 regulatory domain is FCC and country code is US.
4275 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4276 As per FCC smart phone is not a indoor device.
4277 GO should not opeate on indoor channels */
4278void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4279{
4280 int j;
4281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4282 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4283 //Default counrtycode from NV at the time of wiphy initialization.
4284 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4285 &defaultCountryCode[0]))
4286 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004287 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304288 }
4289 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4290 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304291 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4292 {
4293 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4294 return;
4295 }
4296 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4297 {
4298 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4299 // Mark UNII -1 band channel as passive
4300 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4301 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4302 }
4303 }
4304}
4305
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304306/* This function registers for all frame which supplicant is interested in */
4307void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004308{
Jeff Johnson295189b2012-06-20 16:38:30 -07004309 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4310 /* Register for all P2P action, public action etc frames */
4311 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4312
Jeff Johnsone7245742012-09-05 17:12:55 -07004313 ENTER();
4314
Jeff Johnson295189b2012-06-20 16:38:30 -07004315 /* Right now we are registering these frame when driver is getting
4316 initialized. Once we will move to 2.6.37 kernel, in which we have
4317 frame register ops, we will move this code as a part of that */
4318 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304319 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004320 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4321
4322 /* GAS Initial Response */
4323 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4324 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304325
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 /* GAS Comeback Request */
4327 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4328 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4329
4330 /* GAS Comeback Response */
4331 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4332 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4333
4334 /* P2P Public Action */
4335 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304336 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004337 P2P_PUBLIC_ACTION_FRAME_SIZE );
4338
4339 /* P2P Action */
4340 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4341 (v_U8_t*)P2P_ACTION_FRAME,
4342 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004343
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304344 /* WNM BSS Transition Request frame */
4345 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4346 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4347 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004348
4349 /* WNM-Notification */
4350 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4351 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4352 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004353}
4354
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304355void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004356{
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4358 /* Register for all P2P action, public action etc frames */
4359 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4360
Jeff Johnsone7245742012-09-05 17:12:55 -07004361 ENTER();
4362
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 /* Right now we are registering these frame when driver is getting
4364 initialized. Once we will move to 2.6.37 kernel, in which we have
4365 frame register ops, we will move this code as a part of that */
4366 /* GAS Initial Request */
4367
4368 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4369 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4370
4371 /* GAS Initial Response */
4372 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4373 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304374
Jeff Johnson295189b2012-06-20 16:38:30 -07004375 /* GAS Comeback Request */
4376 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4377 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4378
4379 /* GAS Comeback Response */
4380 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4381 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4382
4383 /* P2P Public Action */
4384 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304385 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004386 P2P_PUBLIC_ACTION_FRAME_SIZE );
4387
4388 /* P2P Action */
4389 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4390 (v_U8_t*)P2P_ACTION_FRAME,
4391 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004392 /* WNM-Notification */
4393 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4394 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4395 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004396}
4397
4398#ifdef FEATURE_WLAN_WAPI
4399void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4400 const u8 *mac_addr, u8 *key , int key_Len)
4401{
4402 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4403 tCsrRoamSetKey setKey;
4404 v_BOOL_t isConnected = TRUE;
4405 int status = 0;
4406 v_U32_t roamId= 0xFF;
4407 tANI_U8 *pKeyPtr = NULL;
4408 int n = 0;
4409
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4411 __func__, hdd_device_modetoString(pAdapter->device_mode),
4412 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004413
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304414 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 setKey.keyId = key_index; // Store Key ID
4416 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4417 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4418 setKey.paeRole = 0 ; // the PAE role
4419 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4420 {
4421 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4422 }
4423 else
4424 {
4425 isConnected = hdd_connIsConnected(pHddStaCtx);
4426 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4427 }
4428 setKey.keyLength = key_Len;
4429 pKeyPtr = setKey.Key;
4430 memcpy( pKeyPtr, key, key_Len);
4431
Arif Hussain6d2a3322013-11-17 19:50:10 -08004432 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004433 __func__, key_Len);
4434 for (n = 0 ; n < key_Len; n++)
4435 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4436 __func__,n,setKey.Key[n]);
4437
4438 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4439 if ( isConnected )
4440 {
4441 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4442 pAdapter->sessionId, &setKey, &roamId );
4443 }
4444 if ( status != 0 )
4445 {
4446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4447 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4448 __LINE__, status );
4449 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4450 }
4451}
4452#endif /* FEATURE_WLAN_WAPI*/
4453
4454#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304455int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 beacon_data_t **ppBeacon,
4457 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004458#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304459int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004460 beacon_data_t **ppBeacon,
4461 struct cfg80211_beacon_data *params,
4462 int dtim_period)
4463#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304464{
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 int size;
4466 beacon_data_t *beacon = NULL;
4467 beacon_data_t *old = NULL;
4468 int head_len,tail_len;
4469
Jeff Johnsone7245742012-09-05 17:12:55 -07004470 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004471 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304472 {
4473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4474 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004475 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004477
4478 old = pAdapter->sessionCtx.ap.beacon;
4479
4480 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304481 {
4482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4483 FL("session(%d) old and new heads points to NULL"),
4484 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304486 }
4487
4488 if (params->tail && !params->tail_len)
4489 {
4490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4491 FL("tail_len is zero but tail is not NULL"));
4492 return -EINVAL;
4493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004494
Jeff Johnson295189b2012-06-20 16:38:30 -07004495#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4496 /* Kernel 3.0 is not updating dtim_period for set beacon */
4497 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304498 {
4499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4500 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004503#endif
4504
4505 if(params->head)
4506 head_len = params->head_len;
4507 else
4508 head_len = old->head_len;
4509
4510 if(params->tail || !old)
4511 tail_len = params->tail_len;
4512 else
4513 tail_len = old->tail_len;
4514
4515 size = sizeof(beacon_data_t) + head_len + tail_len;
4516
4517 beacon = kzalloc(size, GFP_KERNEL);
4518
4519 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304520 {
4521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4522 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004523 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004525
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004526#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004527 if(params->dtim_period || !old )
4528 beacon->dtim_period = params->dtim_period;
4529 else
4530 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004531#else
4532 if(dtim_period || !old )
4533 beacon->dtim_period = dtim_period;
4534 else
4535 beacon->dtim_period = old->dtim_period;
4536#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304537
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4539 beacon->tail = beacon->head + head_len;
4540 beacon->head_len = head_len;
4541 beacon->tail_len = tail_len;
4542
4543 if(params->head) {
4544 memcpy (beacon->head,params->head,beacon->head_len);
4545 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304546 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 if(old)
4548 memcpy (beacon->head,old->head,beacon->head_len);
4549 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304550
Jeff Johnson295189b2012-06-20 16:38:30 -07004551 if(params->tail) {
4552 memcpy (beacon->tail,params->tail,beacon->tail_len);
4553 }
4554 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304555 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 memcpy (beacon->tail,old->tail,beacon->tail_len);
4557 }
4558
4559 *ppBeacon = beacon;
4560
4561 kfree(old);
4562
4563 return 0;
4564
4565}
Jeff Johnson295189b2012-06-20 16:38:30 -07004566
4567v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4568{
4569 int left = length;
4570 v_U8_t *ptr = pIes;
4571 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304572
Jeff Johnson295189b2012-06-20 16:38:30 -07004573 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304574 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 elem_id = ptr[0];
4576 elem_len = ptr[1];
4577 left -= 2;
4578 if(elem_len > left)
4579 {
4580 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004581 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004582 eid,elem_len,left);
4583 return NULL;
4584 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304585 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 {
4587 return ptr;
4588 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304589
Jeff Johnson295189b2012-06-20 16:38:30 -07004590 left -= elem_len;
4591 ptr += (elem_len + 2);
4592 }
4593 return NULL;
4594}
4595
Jeff Johnson295189b2012-06-20 16:38:30 -07004596/* Check if rate is 11g rate or not */
4597static int wlan_hdd_rate_is_11g(u8 rate)
4598{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004599 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004600 u8 i;
4601 for (i = 0; i < 8; i++)
4602 {
4603 if(rate == gRateArray[i])
4604 return TRUE;
4605 }
4606 return FALSE;
4607}
4608
4609/* Check for 11g rate and set proper 11g only mode */
4610static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4611 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4612{
4613 u8 i, num_rates = pIe[0];
4614
4615 pIe += 1;
4616 for ( i = 0; i < num_rates; i++)
4617 {
4618 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4619 {
4620 /* If rate set have 11g rate than change the mode to 11G */
4621 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4622 if (pIe[i] & BASIC_RATE_MASK)
4623 {
4624 /* If we have 11g rate as basic rate, it means mode
4625 is 11g only mode.
4626 */
4627 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4628 *pCheckRatesfor11g = FALSE;
4629 }
4630 }
4631 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4632 {
4633 *require_ht = TRUE;
4634 }
4635 }
4636 return;
4637}
4638
4639static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4640{
4641 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4642 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4643 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4644 u8 checkRatesfor11g = TRUE;
4645 u8 require_ht = FALSE;
4646 u8 *pIe=NULL;
4647
4648 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4649
4650 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4651 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4652 if (pIe != NULL)
4653 {
4654 pIe += 1;
4655 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4656 &pConfig->SapHw_mode);
4657 }
4658
4659 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4660 WLAN_EID_EXT_SUPP_RATES);
4661 if (pIe != NULL)
4662 {
4663
4664 pIe += 1;
4665 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4666 &pConfig->SapHw_mode);
4667 }
4668
4669 if( pConfig->channel > 14 )
4670 {
4671 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4672 }
4673
4674 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4675 WLAN_EID_HT_CAPABILITY);
4676
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304677 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 {
4679 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4680 if(require_ht)
4681 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4682 }
4683}
4684
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304685static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4686 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4687{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004688 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304689 v_U8_t *pIe = NULL;
4690 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4691
4692 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4693 pBeacon->tail, pBeacon->tail_len);
4694
4695 if (pIe)
4696 {
4697 ielen = pIe[1] + 2;
4698 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4699 {
4700 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4701 }
4702 else
4703 {
4704 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4705 return -EINVAL;
4706 }
4707 *total_ielen += ielen;
4708 }
4709 return 0;
4710}
4711
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004712static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4713 v_U8_t *genie, v_U8_t *total_ielen)
4714{
4715 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4716 int left = pBeacon->tail_len;
4717 v_U8_t *ptr = pBeacon->tail;
4718 v_U8_t elem_id, elem_len;
4719 v_U16_t ielen = 0;
4720
4721 if ( NULL == ptr || 0 == left )
4722 return;
4723
4724 while (left >= 2)
4725 {
4726 elem_id = ptr[0];
4727 elem_len = ptr[1];
4728 left -= 2;
4729 if (elem_len > left)
4730 {
4731 hddLog( VOS_TRACE_LEVEL_ERROR,
4732 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4733 elem_id, elem_len, left);
4734 return;
4735 }
4736 if (IE_EID_VENDOR == elem_id)
4737 {
4738 /* skipping the VSIE's which we don't want to include or
4739 * it will be included by existing code
4740 */
4741 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4742#ifdef WLAN_FEATURE_WFD
4743 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4744#endif
4745 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4746 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4747 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4748 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4749 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4750 {
4751 ielen = ptr[1] + 2;
4752 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4753 {
4754 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4755 *total_ielen += ielen;
4756 }
4757 else
4758 {
4759 hddLog( VOS_TRACE_LEVEL_ERROR,
4760 "IE Length is too big "
4761 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4762 elem_id, elem_len, *total_ielen);
4763 }
4764 }
4765 }
4766
4767 left -= elem_len;
4768 ptr += (elem_len + 2);
4769 }
4770 return;
4771}
4772
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004773#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004774static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4775 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004776#else
4777static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4778 struct cfg80211_beacon_data *params)
4779#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004780{
4781 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304782 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004783 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004784 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004785
4786 genie = vos_mem_malloc(MAX_GENIE_LEN);
4787
4788 if(genie == NULL) {
4789
4790 return -ENOMEM;
4791 }
4792
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304793 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4794 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004795 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304796 hddLog(LOGE,
4797 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304798 ret = -EINVAL;
4799 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 }
4801
4802#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304803 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4804 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4805 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304806 hddLog(LOGE,
4807 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304808 ret = -EINVAL;
4809 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004810 }
4811#endif
4812
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304813 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4814 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304816 hddLog(LOGE,
4817 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304818 ret = -EINVAL;
4819 goto done;
4820 }
4821
4822 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4823 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004824 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004826
4827 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4828 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4829 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4830 {
4831 hddLog(LOGE,
4832 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004833 ret = -EINVAL;
4834 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004835 }
4836
4837 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4838 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4839 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4840 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4841 ==eHAL_STATUS_FAILURE)
4842 {
4843 hddLog(LOGE,
4844 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004845 ret = -EINVAL;
4846 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 }
4848
4849 // Added for ProResp IE
4850 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4851 {
4852 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4853 u8 probe_rsp_ie_len[3] = {0};
4854 u8 counter = 0;
4855 /* Check Probe Resp Length if it is greater then 255 then Store
4856 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4857 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4858 Store More then 255 bytes into One Variable.
4859 */
4860 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4861 {
4862 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4863 {
4864 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4865 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4866 }
4867 else
4868 {
4869 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4870 rem_probe_resp_ie_len = 0;
4871 }
4872 }
4873
4874 rem_probe_resp_ie_len = 0;
4875
4876 if (probe_rsp_ie_len[0] > 0)
4877 {
4878 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4879 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4880 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4881 probe_rsp_ie_len[0], NULL,
4882 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4883 {
4884 hddLog(LOGE,
4885 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004886 ret = -EINVAL;
4887 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004888 }
4889 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4890 }
4891
4892 if (probe_rsp_ie_len[1] > 0)
4893 {
4894 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4895 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4896 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4897 probe_rsp_ie_len[1], NULL,
4898 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4899 {
4900 hddLog(LOGE,
4901 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004902 ret = -EINVAL;
4903 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 }
4905 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4906 }
4907
4908 if (probe_rsp_ie_len[2] > 0)
4909 {
4910 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4911 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4912 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4913 probe_rsp_ie_len[2], NULL,
4914 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4915 {
4916 hddLog(LOGE,
4917 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004918 ret = -EINVAL;
4919 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 }
4921 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4922 }
4923
4924 if (probe_rsp_ie_len[1] == 0 )
4925 {
4926 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4927 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4928 eANI_BOOLEAN_FALSE) )
4929 {
4930 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004931 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 }
4933 }
4934
4935 if (probe_rsp_ie_len[2] == 0 )
4936 {
4937 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4938 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4939 eANI_BOOLEAN_FALSE) )
4940 {
4941 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004942 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 }
4944 }
4945
4946 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4947 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4948 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4949 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4950 == eHAL_STATUS_FAILURE)
4951 {
4952 hddLog(LOGE,
4953 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004954 ret = -EINVAL;
4955 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 }
4957 }
4958 else
4959 {
4960 // Reset WNI_CFG_PROBE_RSP Flags
4961 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
4962
4963 hddLog(VOS_TRACE_LEVEL_INFO,
4964 "%s: No Probe Response IE received in set beacon",
4965 __func__);
4966 }
4967
4968 // Added for AssocResp IE
4969 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
4970 {
4971 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4972 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
4973 params->assocresp_ies_len, NULL,
4974 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4975 {
4976 hddLog(LOGE,
4977 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004978 ret = -EINVAL;
4979 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 }
4981
4982 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4983 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
4984 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4985 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4986 == eHAL_STATUS_FAILURE)
4987 {
4988 hddLog(LOGE,
4989 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004990 ret = -EINVAL;
4991 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 }
4993 }
4994 else
4995 {
4996 hddLog(VOS_TRACE_LEVEL_INFO,
4997 "%s: No Assoc Response IE received in set beacon",
4998 __func__);
4999
5000 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5001 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5002 eANI_BOOLEAN_FALSE) )
5003 {
5004 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005005 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005006 }
5007 }
5008
Jeff Johnsone7245742012-09-05 17:12:55 -07005009done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005010 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305011 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005012}
Jeff Johnson295189b2012-06-20 16:38:30 -07005013
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 * FUNCTION: wlan_hdd_validate_operation_channel
5016 * called by wlan_hdd_cfg80211_start_bss() and
5017 * wlan_hdd_cfg80211_set_channel()
5018 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305019 * channel list.
5020 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005021VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305023
Jeff Johnson295189b2012-06-20 16:38:30 -07005024 v_U32_t num_ch = 0;
5025 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5026 u32 indx = 0;
5027 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305028 v_U8_t fValidChannel = FALSE, count = 0;
5029 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305030
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5032
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305033 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305035 /* Validate the channel */
5036 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305038 if ( channel == rfChannels[count].channelNum )
5039 {
5040 fValidChannel = TRUE;
5041 break;
5042 }
5043 }
5044 if (fValidChannel != TRUE)
5045 {
5046 hddLog(VOS_TRACE_LEVEL_ERROR,
5047 "%s: Invalid Channel [%d]", __func__, channel);
5048 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 }
5050 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305051 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305053 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5054 valid_ch, &num_ch))
5055 {
5056 hddLog(VOS_TRACE_LEVEL_ERROR,
5057 "%s: failed to get valid channel list", __func__);
5058 return VOS_STATUS_E_FAILURE;
5059 }
5060 for (indx = 0; indx < num_ch; indx++)
5061 {
5062 if (channel == valid_ch[indx])
5063 {
5064 break;
5065 }
5066 }
5067
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305068 if (indx >= num_ch)
5069 {
5070 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5071 {
5072 eCsrBand band;
5073 unsigned int freq;
5074
5075 sme_GetFreqBand(hHal, &band);
5076
5077 if (eCSR_BAND_5G == band)
5078 {
5079#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5080 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5081 {
5082 freq = ieee80211_channel_to_frequency(channel,
5083 IEEE80211_BAND_2GHZ);
5084 }
5085 else
5086 {
5087 freq = ieee80211_channel_to_frequency(channel,
5088 IEEE80211_BAND_5GHZ);
5089 }
5090#else
5091 freq = ieee80211_channel_to_frequency(channel);
5092#endif
5093 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5094 return VOS_STATUS_SUCCESS;
5095 }
5096 }
5097
5098 hddLog(VOS_TRACE_LEVEL_ERROR,
5099 "%s: Invalid Channel [%d]", __func__, channel);
5100 return VOS_STATUS_E_FAILURE;
5101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305103
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106}
5107
Viral Modi3a32cc52013-02-08 11:14:52 -08005108/**
5109 * FUNCTION: wlan_hdd_cfg80211_set_channel
5110 * This function is used to set the channel number
5111 */
5112static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5113 struct ieee80211_channel *chan,
5114 enum nl80211_channel_type channel_type
5115 )
5116{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305117 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005118 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005119 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005120 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305121 hdd_context_t *pHddCtx;
5122 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005123
5124 ENTER();
5125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305126
Viral Modi3a32cc52013-02-08 11:14:52 -08005127 if( NULL == dev )
5128 {
5129 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005130 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005131 return -ENODEV;
5132 }
5133 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5136 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5137 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005138 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305139 "%s: device_mode = %s (%d) freq = %d", __func__,
5140 hdd_device_modetoString(pAdapter->device_mode),
5141 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305142
5143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5144 status = wlan_hdd_validate_context(pHddCtx);
5145
5146 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5149 "%s: HDD context is not valid", __func__);
5150 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005151 }
5152
5153 /*
5154 * Do freq to chan conversion
5155 * TODO: for 11a
5156 */
5157
5158 channel = ieee80211_frequency_to_channel(freq);
5159
5160 /* Check freq range */
5161 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5162 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5163 {
5164 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005165 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005166 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5167 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5168 return -EINVAL;
5169 }
5170
5171 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5172
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305173 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5174 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005175 {
5176 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5177 {
5178 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005179 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005180 return -EINVAL;
5181 }
5182 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5183 "%s: set channel to [%d] for device mode =%d",
5184 __func__, channel,pAdapter->device_mode);
5185 }
5186 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005187 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005188 )
5189 {
5190 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5191 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5192 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5193
5194 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5195 {
5196 /* Link is up then return cant set channel*/
5197 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005198 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005199 return -EINVAL;
5200 }
5201
5202 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5203 pHddStaCtx->conn_info.operationChannel = channel;
5204 pRoamProfile->ChannelInfo.ChannelList =
5205 &pHddStaCtx->conn_info.operationChannel;
5206 }
5207 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005208 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005209 )
5210 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305211 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5212 {
5213 if(VOS_STATUS_SUCCESS !=
5214 wlan_hdd_validate_operation_channel(pAdapter,channel))
5215 {
5216 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005217 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305218 return -EINVAL;
5219 }
5220 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5221 }
5222 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005223 {
5224 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5225
5226 /* If auto channel selection is configured as enable/ 1 then ignore
5227 channel set by supplicant
5228 */
5229 if ( cfg_param->apAutoChannelSelection )
5230 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305231 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5232 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005233 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305234 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5235 __func__, hdd_device_modetoString(pAdapter->device_mode),
5236 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005237 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305238 else
5239 {
5240 if(VOS_STATUS_SUCCESS !=
5241 wlan_hdd_validate_operation_channel(pAdapter,channel))
5242 {
5243 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005244 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305245 return -EINVAL;
5246 }
5247 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5248 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005249 }
5250 }
5251 else
5252 {
5253 hddLog(VOS_TRACE_LEVEL_FATAL,
5254 "%s: Invalid device mode failed to set valid channel", __func__);
5255 return -EINVAL;
5256 }
5257 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305258 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005259}
5260
Jeff Johnson295189b2012-06-20 16:38:30 -07005261#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5262static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5263 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005264#else
5265static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5266 struct cfg80211_beacon_data *params,
5267 const u8 *ssid, size_t ssid_len,
5268 enum nl80211_hidden_ssid hidden_ssid)
5269#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005270{
5271 tsap_Config_t *pConfig;
5272 beacon_data_t *pBeacon = NULL;
5273 struct ieee80211_mgmt *pMgmt_frame;
5274 v_U8_t *pIe=NULL;
5275 v_U16_t capab_info;
5276 eCsrAuthType RSNAuthType;
5277 eCsrEncryptionType RSNEncryptType;
5278 eCsrEncryptionType mcRSNEncryptType;
5279 int status = VOS_STATUS_SUCCESS;
5280 tpWLAN_SAPEventCB pSapEventCallback;
5281 hdd_hostapd_state_t *pHostapdState;
5282 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5283 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305284 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005285 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305286 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005288 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005289 v_BOOL_t MFPCapable = VOS_FALSE;
5290 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305291 eHddDot11Mode sapDot11Mode =
5292 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005293
5294 ENTER();
5295
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305296 iniConfig = pHddCtx->cfg_ini;
5297
Jeff Johnson295189b2012-06-20 16:38:30 -07005298 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5299
5300 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5301
5302 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5303
5304 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5305
5306 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5307
5308 //channel is already set in the set_channel Call back
5309 //pConfig->channel = pCommitConfig->channel;
5310
5311 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305312 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005313 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5314
5315 pConfig->dtim_period = pBeacon->dtim_period;
5316
Arif Hussain6d2a3322013-11-17 19:50:10 -08005317 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 pConfig->dtim_period);
5319
5320
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005321 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005322 {
5323 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005324 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305325 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5326 {
5327 tANI_BOOLEAN restartNeeded;
5328 pConfig->ieee80211d = 1;
5329 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5330 sme_setRegInfo(hHal, pConfig->countryCode);
5331 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5332 }
5333 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005335 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005336 pConfig->ieee80211d = 1;
5337 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5338 sme_setRegInfo(hHal, pConfig->countryCode);
5339 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005341 else
5342 {
5343 pConfig->ieee80211d = 0;
5344 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305345 /*
5346 * If auto channel is configured i.e. channel is 0,
5347 * so skip channel validation.
5348 */
5349 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5350 {
5351 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5352 {
5353 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005354 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305355 return -EINVAL;
5356 }
5357 }
5358 else
5359 {
5360 if(1 != pHddCtx->is_dynamic_channel_range_set)
5361 {
5362 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5363 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5364 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5365 }
5366 pHddCtx->is_dynamic_channel_range_set = 0;
5367 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005369 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005370 {
5371 pConfig->ieee80211d = 0;
5372 }
5373 pConfig->authType = eSAP_AUTO_SWITCH;
5374
5375 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305376
5377 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005378 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5379
5380 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5381
5382 /*Set wps station to configured*/
5383 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5384
5385 if(pIe)
5386 {
5387 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5388 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005389 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005390 return -EINVAL;
5391 }
5392 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5393 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005394 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 /* Check 15 bit of WPS IE as it contain information for wps state
5396 * WPS state
5397 */
5398 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5399 {
5400 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5401 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5402 {
5403 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5404 }
5405 }
5406 }
5407 else
5408 {
5409 pConfig->wps_state = SAP_WPS_DISABLED;
5410 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305411 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005412
c_hpothufe599e92014-06-16 11:38:55 +05305413 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5414 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5415 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5416 eCSR_ENCRYPT_TYPE_NONE;
5417
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 pConfig->RSNWPAReqIELength = 0;
5419 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305420 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 WLAN_EID_RSN);
5422 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305423 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5425 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5426 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305427 /* The actual processing may eventually be more extensive than
5428 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 * by the app.
5430 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305431 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5433 &RSNEncryptType,
5434 &mcRSNEncryptType,
5435 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005436 &MFPCapable,
5437 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 pConfig->pRSNWPAReqIE[1]+2,
5439 pConfig->pRSNWPAReqIE );
5440
5441 if( VOS_STATUS_SUCCESS == status )
5442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305443 /* Now copy over all the security attributes you have
5444 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 * */
5446 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5447 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5448 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5449 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305450 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005451 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5453 }
5454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305455
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5457 pBeacon->tail, pBeacon->tail_len);
5458
5459 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5460 {
5461 if (pConfig->pRSNWPAReqIE)
5462 {
5463 /*Mixed mode WPA/WPA2*/
5464 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5465 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5466 }
5467 else
5468 {
5469 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5470 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5471 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305472 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5474 &RSNEncryptType,
5475 &mcRSNEncryptType,
5476 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005477 &MFPCapable,
5478 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 pConfig->pRSNWPAReqIE[1]+2,
5480 pConfig->pRSNWPAReqIE );
5481
5482 if( VOS_STATUS_SUCCESS == status )
5483 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305484 /* Now copy over all the security attributes you have
5485 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 * */
5487 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5488 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5489 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5490 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305491 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005492 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5494 }
5495 }
5496 }
5497
Jeff Johnson4416a782013-03-25 14:17:50 -07005498 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5499 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5500 return -EINVAL;
5501 }
5502
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5504
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005505#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 if (params->ssid != NULL)
5507 {
5508 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5509 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5510 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5511 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5512 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005513#else
5514 if (ssid != NULL)
5515 {
5516 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5517 pConfig->SSIDinfo.ssid.length = ssid_len;
5518 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5519 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5520 }
5521#endif
5522
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305523 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305525
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 /* default value */
5527 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5528 pConfig->num_accept_mac = 0;
5529 pConfig->num_deny_mac = 0;
5530
5531 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5532 pBeacon->tail, pBeacon->tail_len);
5533
5534 /* pIe for black list is following form:
5535 type : 1 byte
5536 length : 1 byte
5537 OUI : 4 bytes
5538 acl type : 1 byte
5539 no of mac addr in black list: 1 byte
5540 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305541 */
5542 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 {
5544 pConfig->SapMacaddr_acl = pIe[6];
5545 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005546 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005547 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305548 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5549 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5551 for (i = 0; i < pConfig->num_deny_mac; i++)
5552 {
5553 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5554 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305555 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 }
5557 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5558 pBeacon->tail, pBeacon->tail_len);
5559
5560 /* pIe for white list is following form:
5561 type : 1 byte
5562 length : 1 byte
5563 OUI : 4 bytes
5564 acl type : 1 byte
5565 no of mac addr in white list: 1 byte
5566 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305567 */
5568 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 {
5570 pConfig->SapMacaddr_acl = pIe[6];
5571 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005572 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005573 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305574 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5575 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5577 for (i = 0; i < pConfig->num_accept_mac; i++)
5578 {
5579 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5580 acl_entry++;
5581 }
5582 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305583
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5585
Jeff Johnsone7245742012-09-05 17:12:55 -07005586#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005587 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305588 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5589 * 11ac in .ini and 11ac is supported by both host and firmware.
5590 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5591 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005592 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5593 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305594 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5595 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5596 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5597 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5598 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005599 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305600 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005601 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305602 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005603
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305604 /* If ACS disable and selected channel <= 14
5605 * OR
5606 * ACS enabled and ACS operating band is choosen as 2.4
5607 * AND
5608 * VHT in 2.4G Disabled
5609 * THEN
5610 * Fallback to 11N mode
5611 */
5612 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5613 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305614 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305615 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005616 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305617 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5618 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005619 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5620 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005621 }
5622#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305623
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005624 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5625 {
5626 sme_SelectCBMode(hHal,
5627 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5628 pConfig->channel);
5629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005630 // ht_capab is not what the name conveys,this is used for protection bitmap
5631 pConfig->ht_capab =
5632 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5633
5634 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5635 {
5636 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5637 return -EINVAL;
5638 }
5639
5640 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5643 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305644 pConfig->obssProtEnabled =
5645 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005646
Chet Lanctot8cecea22014-02-11 19:09:36 -08005647#ifdef WLAN_FEATURE_11W
5648 pConfig->mfpCapable = MFPCapable;
5649 pConfig->mfpRequired = MFPRequired;
5650 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5651 pConfig->mfpCapable, pConfig->mfpRequired);
5652#endif
5653
Arif Hussain6d2a3322013-11-17 19:50:10 -08005654 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005656 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5657 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5658 (int)pConfig->channel);
5659 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5660 pConfig->SapHw_mode, pConfig->privacy,
5661 pConfig->authType);
5662 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5663 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5664 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5665 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005666
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305667 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 {
5669 //Bss already started. just return.
5670 //TODO Probably it should update some beacon params.
5671 hddLog( LOGE, "Bss Already started...Ignore the request");
5672 EXIT();
5673 return 0;
5674 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305675
Jeff Johnson295189b2012-06-20 16:38:30 -07005676 pConfig->persona = pHostapdAdapter->device_mode;
5677
5678 pSapEventCallback = hdd_hostapd_SAPEventCB;
5679 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5680 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5681 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005682 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005683 return -EINVAL;
5684 }
5685
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305686 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5688
5689 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305690
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692 {
5693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005694 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005695 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 VOS_ASSERT(0);
5697 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305698
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5700
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005701#ifdef WLAN_FEATURE_P2P_DEBUG
5702 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5703 {
5704 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5705 {
5706 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5707 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005708 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005709 }
5710 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5711 {
5712 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5713 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005714 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005715 }
5716 }
5717#endif
5718
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 pHostapdState->bCommit = TRUE;
5720 EXIT();
5721
5722 return 0;
5723}
5724
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005725#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305726static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5727 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 struct beacon_parameters *params)
5729{
5730 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305731 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305732 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005733
5734 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5737 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5738 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305739 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5740 hdd_device_modetoString(pAdapter->device_mode),
5741 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005742
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305743 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5744 status = wlan_hdd_validate_context(pHddCtx);
5745
5746 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005747 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5749 "%s: HDD context is not valid", __func__);
5750 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005751 }
5752
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305753 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 )
5756 {
5757 beacon_data_t *old,*new;
5758
5759 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305760
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305762 {
5763 hddLog(VOS_TRACE_LEVEL_WARN,
5764 FL("already beacon info added to session(%d)"),
5765 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005768
5769 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5770
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305771 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 {
5773 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005774 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 return -EINVAL;
5776 }
5777
5778 pAdapter->sessionCtx.ap.beacon = new;
5779
5780 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5781 }
5782
5783 EXIT();
5784 return status;
5785}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786
5787static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 struct net_device *dev,
5789 struct beacon_parameters *params)
5790{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305792 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5793 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305794 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005795
5796 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5798 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5799 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5801 __func__, hdd_device_modetoString(pAdapter->device_mode),
5802 pAdapter->device_mode);
5803
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5805 status = wlan_hdd_validate_context(pHddCtx);
5806
5807 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005808 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5810 "%s: HDD context is not valid", __func__);
5811 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005812 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305813
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305814 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305816 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 {
5818 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305823 {
5824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5825 FL("session(%d) old and new heads points to NULL"),
5826 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005829
5830 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5831
5832 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005834 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 return -EINVAL;
5836 }
5837
5838 pAdapter->sessionCtx.ap.beacon = new;
5839
5840 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5841 }
5842
5843 EXIT();
5844 return status;
5845}
5846
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005847#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5848
5849#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005850static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5851 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005852#else
5853static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5854 struct net_device *dev)
5855#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005856{
5857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005858 hdd_context_t *pHddCtx = NULL;
5859 hdd_scaninfo_t *pScanInfo = NULL;
5860 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305861 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305862 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005863
5864 ENTER();
5865
5866 if (NULL == pAdapter)
5867 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005869 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 return -ENODEV;
5871 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5874 TRACE_CODE_HDD_CFG80211_STOP_AP,
5875 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305876 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5877 status = wlan_hdd_validate_context(pHddCtx);
5878
5879 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005880 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5882 "%s: HDD context is not valid", __func__);
5883 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005884 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005885
5886 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5887 if (NULL == staAdapter)
5888 {
5889 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5890 if (NULL == staAdapter)
5891 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5893 "%s: HDD adapter context for STA/P2P-CLI is Null",
5894 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005895 }
5896 }
5897
5898 pScanInfo = &pHddCtx->scan_info;
5899
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5901 __func__, hdd_device_modetoString(pAdapter->device_mode),
5902 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005903
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305904 ret = wlan_hdd_scan_abort(pAdapter);
5905
Girish Gowli4bf7a632014-06-12 13:42:11 +05305906 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005907 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5909 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305910
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305911 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005912 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5914 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005915
Jeff Johnsone7245742012-09-05 17:12:55 -07005916 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305917 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005918 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305919 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005920 }
5921
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305922 hdd_hostapd_stop(dev);
5923
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 )
5927 {
5928 beacon_data_t *old;
5929
5930 old = pAdapter->sessionCtx.ap.beacon;
5931
5932 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305933 {
5934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5935 FL("session(%d) beacon data points to NULL"),
5936 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005939
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005941
5942 mutex_lock(&pHddCtx->sap_lock);
5943 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5944 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005945 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 {
5947 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5948
5949 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5950
5951 if (!VOS_IS_STATUS_SUCCESS(status))
5952 {
5953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005954 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305956 }
5957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
5959 }
5960 mutex_unlock(&pHddCtx->sap_lock);
5961
5962 if(status != VOS_STATUS_SUCCESS)
5963 {
5964 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005965 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 return -EINVAL;
5967 }
5968
Jeff Johnson4416a782013-03-25 14:17:50 -07005969 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
5971 ==eHAL_STATUS_FAILURE)
5972 {
5973 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005974 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 }
5976
Jeff Johnson4416a782013-03-25 14:17:50 -07005977 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5979 eANI_BOOLEAN_FALSE) )
5980 {
5981 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005982 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 }
5984
5985 // Reset WNI_CFG_PROBE_RSP Flags
5986 wlan_hdd_reset_prob_rspies(pAdapter);
5987
5988 pAdapter->sessionCtx.ap.beacon = NULL;
5989 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005990#ifdef WLAN_FEATURE_P2P_DEBUG
5991 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
5992 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
5993 {
5994 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
5995 "GO got removed");
5996 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
5997 }
5998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 }
6000 EXIT();
6001 return status;
6002}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006003
6004#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6005
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306006static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6007 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006008 struct cfg80211_ap_settings *params)
6009{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306010 hdd_adapter_t *pAdapter;
6011 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306012 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006013
6014 ENTER();
6015
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306016 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006017 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306019 "%s: Device is Null", __func__);
6020 return -ENODEV;
6021 }
6022
6023 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6024 if (NULL == pAdapter)
6025 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306027 "%s: HDD adapter is Null", __func__);
6028 return -ENODEV;
6029 }
6030
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6032 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6033 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306034 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6035 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306037 "%s: HDD adapter magic is invalid", __func__);
6038 return -ENODEV;
6039 }
6040
6041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306042 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306043
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306044 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6047 "%s: HDD context is not valid", __func__);
6048 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306049 }
6050
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306051 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6052 __func__, hdd_device_modetoString(pAdapter->device_mode),
6053 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306054
6055 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006056 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006057 )
6058 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306059 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006060
6061 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306062
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006063 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306064 {
6065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6066 FL("already beacon info added to session(%d)"),
6067 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006068 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306069 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006070
6071 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6072
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306073 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006074 {
6075 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306076 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006077 return -EINVAL;
6078 }
6079 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006080#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006081 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6082#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6083 params->channel, params->channel_type);
6084#else
6085 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6086#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006087#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006088 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6089 params->ssid_len, params->hidden_ssid);
6090 }
6091
6092 EXIT();
6093 return status;
6094}
6095
6096
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306097static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006098 struct net_device *dev,
6099 struct cfg80211_beacon_data *params)
6100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306102 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306103 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006104
6105 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306106
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306107 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6108 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6109 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006110 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006111 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306112
6113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6114 status = wlan_hdd_validate_context(pHddCtx);
6115
6116 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006117 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6119 "%s: HDD context is not valid", __func__);
6120 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006121 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006122
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006124 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006126 {
6127 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006129 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306130
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006131 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306132 {
6133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6134 FL("session(%d) beacon data points to NULL"),
6135 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006136 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306137 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006138
6139 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6140
6141 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006143 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006144 return -EINVAL;
6145 }
6146
6147 pAdapter->sessionCtx.ap.beacon = new;
6148
6149 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6150 }
6151
6152 EXIT();
6153 return status;
6154}
6155
6156#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6157
Jeff Johnson295189b2012-06-20 16:38:30 -07006158
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306159static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 struct net_device *dev,
6161 struct bss_parameters *params)
6162{
6163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6164
6165 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306166
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6168 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6169 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6171 __func__, hdd_device_modetoString(pAdapter->device_mode),
6172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006173
6174 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306176 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 {
6178 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6179 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306180 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 {
6182 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006184 }
6185
6186 EXIT();
6187 return 0;
6188}
6189
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306190static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6191 struct net_device *dev,
6192 struct bss_parameters *params)
6193{
6194 int ret;
6195
6196 vos_ssr_protect(__func__);
6197 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6198 vos_ssr_unprotect(__func__);
6199
6200 return ret;
6201}
Kiet Lam10841362013-11-01 11:36:50 +05306202/* FUNCTION: wlan_hdd_change_country_code_cd
6203* to wait for contry code completion
6204*/
6205void* wlan_hdd_change_country_code_cb(void *pAdapter)
6206{
6207 hdd_adapter_t *call_back_pAdapter = pAdapter;
6208 complete(&call_back_pAdapter->change_country_code);
6209 return NULL;
6210}
6211
Jeff Johnson295189b2012-06-20 16:38:30 -07006212/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306213 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6215 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306216int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 struct net_device *ndev,
6218 enum nl80211_iftype type,
6219 u32 *flags,
6220 struct vif_params *params
6221 )
6222{
6223 struct wireless_dev *wdev;
6224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006225 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006226 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 tCsrRoamProfile *pRoamProfile = NULL;
6228 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306229 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 eMib_dot11DesiredBssType connectedBssType;
6231 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306232 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006233
6234 ENTER();
6235
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306236 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006237 {
6238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6239 "%s: Adapter context is null", __func__);
6240 return VOS_STATUS_E_FAILURE;
6241 }
6242
6243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6244 if (!pHddCtx)
6245 {
6246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 "%s: HDD context is null", __func__);
6248 return VOS_STATUS_E_FAILURE;
6249 }
6250
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306251 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6252 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6253 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306254 status = wlan_hdd_validate_context(pHddCtx);
6255
6256 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6259 "%s: HDD context is not valid", __func__);
6260 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 }
6262
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306263 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6264 __func__, hdd_device_modetoString(pAdapter->device_mode),
6265 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006266
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306267 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 wdev = ndev->ieee80211_ptr;
6269
6270#ifdef WLAN_BTAMP_FEATURE
6271 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6272 (NL80211_IFTYPE_ADHOC == type)||
6273 (NL80211_IFTYPE_AP == type)||
6274 (NL80211_IFTYPE_P2P_GO == type))
6275 {
6276 pHddCtx->isAmpAllowed = VOS_FALSE;
6277 // stop AMP traffic
6278 status = WLANBAP_StopAmp();
6279 if(VOS_STATUS_SUCCESS != status )
6280 {
6281 pHddCtx->isAmpAllowed = VOS_TRUE;
6282 hddLog(VOS_TRACE_LEVEL_FATAL,
6283 "%s: Failed to stop AMP", __func__);
6284 return -EINVAL;
6285 }
6286 }
6287#endif //WLAN_BTAMP_FEATURE
6288 /* Reset the current device mode bit mask*/
6289 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6290
6291 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006293 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 )
6295 {
6296 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006297 if (!pWextState)
6298 {
6299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6300 "%s: pWextState is null", __func__);
6301 return VOS_STATUS_E_FAILURE;
6302 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 pRoamProfile = &pWextState->roamProfile;
6304 LastBSSType = pRoamProfile->BSSType;
6305
6306 switch (type)
6307 {
6308 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 hddLog(VOS_TRACE_LEVEL_INFO,
6311 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6312 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006313#ifdef WLAN_FEATURE_11AC
6314 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6315 {
6316 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6317 }
6318#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006320 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006322 //Check for sub-string p2p to confirm its a p2p interface
6323 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006325 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6326 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6327 }
6328 else
6329 {
6330 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006332 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306333#ifdef FEATURE_WLAN_TDLS
6334 /* The open adapter for the p2p shall skip initializations in
6335 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6336 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6337 * tdls_init when the change_iface sets the device mode to
6338 * WLAN_HDD_P2P_CLIENT.
6339 */
6340
6341 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6342 {
6343 if (0 != wlan_hdd_tdls_init (pAdapter))
6344 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306345 hddLog(VOS_TRACE_LEVEL_ERROR,
6346 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306347 return -EINVAL;
6348 }
6349 }
6350#endif
6351
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 break;
6353 case NL80211_IFTYPE_ADHOC:
6354 hddLog(VOS_TRACE_LEVEL_INFO,
6355 "%s: setting interface Type to ADHOC", __func__);
6356 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6357 pRoamProfile->phyMode =
6358 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006359 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 wdev->iftype = type;
6361 break;
6362
6363 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 {
6366 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6367 "%s: setting interface Type to %s", __func__,
6368 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6369
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006370 //Cancel any remain on channel for GO mode
6371 if (NL80211_IFTYPE_P2P_GO == type)
6372 {
6373 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6374 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006375 if (NL80211_IFTYPE_AP == type)
6376 {
6377 /* As Loading WLAN Driver one interface being created for p2p device
6378 * address. This will take one HW STA and the max number of clients
6379 * that can connect to softAP will be reduced by one. so while changing
6380 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6381 * interface as it is not required in SoftAP mode.
6382 */
6383
6384 // Get P2P Adapter
6385 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6386
6387 if (pP2pAdapter)
6388 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306389 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006390 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6391 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6392 }
6393 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306394 //Disable IMPS & BMPS for SAP/GO
6395 if(VOS_STATUS_E_FAILURE ==
6396 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6397 {
6398 //Fail to Exit BMPS
6399 VOS_ASSERT(0);
6400 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306401#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006402
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306403 /* A Mutex Lock is introduced while changing the mode to
6404 * protect the concurrent access for the Adapters by TDLS
6405 * module.
6406 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306407 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306408#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306410 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 hdd_deinit_adapter( pHddCtx, pAdapter );
6412 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6414 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306415#ifdef FEATURE_WLAN_TDLS
6416 mutex_unlock(&pHddCtx->tdls_lock);
6417#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006418 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6419 (pConfig->apRandomBssidEnabled))
6420 {
6421 /* To meet Android requirements create a randomized
6422 MAC address of the form 02:1A:11:Fx:xx:xx */
6423 get_random_bytes(&ndev->dev_addr[3], 3);
6424 ndev->dev_addr[0] = 0x02;
6425 ndev->dev_addr[1] = 0x1A;
6426 ndev->dev_addr[2] = 0x11;
6427 ndev->dev_addr[3] |= 0xF0;
6428 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6429 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006430 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6431 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006432 }
6433
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 hdd_set_ap_ops( pAdapter->dev );
6435
Kiet Lam10841362013-11-01 11:36:50 +05306436 /* This is for only SAP mode where users can
6437 * control country through ini.
6438 * P2P GO follows station country code
6439 * acquired during the STA scanning. */
6440 if((NL80211_IFTYPE_AP == type) &&
6441 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6442 {
6443 int status = 0;
6444 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6445 "%s: setting country code from INI ", __func__);
6446 init_completion(&pAdapter->change_country_code);
6447 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6448 (void *)(tSmeChangeCountryCallback)
6449 wlan_hdd_change_country_code_cb,
6450 pConfig->apCntryCode, pAdapter,
6451 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306452 eSIR_FALSE,
6453 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306454 if (eHAL_STATUS_SUCCESS == status)
6455 {
6456 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306457 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306458 &pAdapter->change_country_code,
6459 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306460 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306461 {
6462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306463 FL("SME Timed out while setting country code %ld"),
6464 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006465
6466 if (pHddCtx->isLogpInProgress)
6467 {
6468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6469 "%s: LOGP in Progress. Ignore!!!", __func__);
6470 return -EAGAIN;
6471 }
Kiet Lam10841362013-11-01 11:36:50 +05306472 }
6473 }
6474 else
6475 {
6476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006477 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306478 return -EINVAL;
6479 }
6480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 status = hdd_init_ap_mode(pAdapter);
6482 if(status != VOS_STATUS_SUCCESS)
6483 {
6484 hddLog(VOS_TRACE_LEVEL_FATAL,
6485 "%s: Error initializing the ap mode", __func__);
6486 return -EINVAL;
6487 }
6488 hdd_set_conparam(1);
6489
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 /*interface type changed update in wiphy structure*/
6491 if(wdev)
6492 {
6493 wdev->iftype = type;
6494 pHddCtx->change_iface = type;
6495 }
6496 else
6497 {
6498 hddLog(VOS_TRACE_LEVEL_ERROR,
6499 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6500 return -EINVAL;
6501 }
6502 goto done;
6503 }
6504
6505 default:
6506 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6507 __func__);
6508 return -EOPNOTSUPP;
6509 }
6510 }
6511 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 )
6514 {
6515 switch(type)
6516 {
6517 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306520#ifdef FEATURE_WLAN_TDLS
6521
6522 /* A Mutex Lock is introduced while changing the mode to
6523 * protect the concurrent access for the Adapters by TDLS
6524 * module.
6525 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306526 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306527#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306528 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006529 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006530 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006531 //Check for sub-string p2p to confirm its a p2p interface
6532 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006533 {
6534 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6535 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6536 }
6537 else
6538 {
6539 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 hdd_set_conparam(0);
6543 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6545 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306546#ifdef FEATURE_WLAN_TDLS
6547 mutex_unlock(&pHddCtx->tdls_lock);
6548#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306549 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 if( VOS_STATUS_SUCCESS != status )
6551 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006552 /* In case of JB, for P2P-GO, only change interface will be called,
6553 * This is the right place to enable back bmps_imps()
6554 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306555 if (pHddCtx->hdd_wlan_suspended)
6556 {
6557 hdd_set_pwrparams(pHddCtx);
6558 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006559 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 goto done;
6561 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6565 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 goto done;
6567 default:
6568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6569 __func__);
6570 return -EOPNOTSUPP;
6571
6572 }
6573
6574 }
6575 else
6576 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306577 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6578 __func__, hdd_device_modetoString(pAdapter->device_mode),
6579 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 return -EOPNOTSUPP;
6581 }
6582
6583
6584 if(pRoamProfile)
6585 {
6586 if ( LastBSSType != pRoamProfile->BSSType )
6587 {
6588 /*interface type changed update in wiphy structure*/
6589 wdev->iftype = type;
6590
6591 /*the BSS mode changed, We need to issue disconnect
6592 if connected or in IBSS disconnect state*/
6593 if ( hdd_connGetConnectedBssType(
6594 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6595 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6596 {
6597 /*need to issue a disconnect to CSR.*/
6598 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6599 if( eHAL_STATUS_SUCCESS ==
6600 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6601 pAdapter->sessionId,
6602 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6603 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306604 ret = wait_for_completion_interruptible_timeout(
6605 &pAdapter->disconnect_comp_var,
6606 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6607 if (ret <= 0)
6608 {
6609 hddLog(VOS_TRACE_LEVEL_ERROR,
6610 FL("wait on disconnect_comp_var failed %ld"), ret);
6611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 }
6613 }
6614 }
6615 }
6616
6617done:
6618 /*set bitmask based on updated value*/
6619 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006620
6621 /* Only STA mode support TM now
6622 * all other mode, TM feature should be disabled */
6623 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6624 (~VOS_STA & pHddCtx->concurrency_mode) )
6625 {
6626 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6627 }
6628
Jeff Johnson295189b2012-06-20 16:38:30 -07006629#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306630 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6632 {
6633 //we are ok to do AMP
6634 pHddCtx->isAmpAllowed = VOS_TRUE;
6635 }
6636#endif //WLAN_BTAMP_FEATURE
6637 EXIT();
6638 return 0;
6639}
6640
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306641/*
6642 * FUNCTION: wlan_hdd_cfg80211_change_iface
6643 * wrapper function to protect the actual implementation from SSR.
6644 */
6645int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6646 struct net_device *ndev,
6647 enum nl80211_iftype type,
6648 u32 *flags,
6649 struct vif_params *params
6650 )
6651{
6652 int ret;
6653
6654 vos_ssr_protect(__func__);
6655 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6656 vos_ssr_unprotect(__func__);
6657
6658 return ret;
6659}
6660
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006661#ifdef FEATURE_WLAN_TDLS
6662static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6663 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6664{
6665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6666 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6667 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006668 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306669 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306670 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006671
6672 ENTER();
6673
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306674 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006675 {
6676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6677 "Invalid arguments");
6678 return -EINVAL;
6679 }
Hoonki Lee27511902013-03-14 18:19:06 -07006680
6681 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6682 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6683 {
6684 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6685 "%s: TDLS mode is disabled OR not enabled in FW."
6686 MAC_ADDRESS_STR " Request declined.",
6687 __func__, MAC_ADDR_ARRAY(mac));
6688 return -ENOTSUPP;
6689 }
6690
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006691 if (pHddCtx->isLogpInProgress)
6692 {
6693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6694 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006695 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006696 return -EBUSY;
6697 }
6698
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306699 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006700
6701 if ( NULL == pTdlsPeer ) {
6702 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6703 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6704 __func__, MAC_ADDR_ARRAY(mac), update);
6705 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006706 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006707
6708 /* in add station, we accept existing valid staId if there is */
6709 if ((0 == update) &&
6710 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6711 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006712 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006713 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006714 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006715 " link_status %d. staId %d. add station ignored.",
6716 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6717 return 0;
6718 }
6719 /* in change station, we accept only when staId is valid */
6720 if ((1 == update) &&
6721 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6722 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6723 {
6724 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6725 "%s: " MAC_ADDRESS_STR
6726 " link status %d. staId %d. change station %s.",
6727 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6728 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6729 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006730 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006731
6732 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306733 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006734 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6736 "%s: " MAC_ADDRESS_STR
6737 " TDLS setup is ongoing. Request declined.",
6738 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006739 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006740 }
6741
6742 /* first to check if we reached to maximum supported TDLS peer.
6743 TODO: for now, return -EPERM looks working fine,
6744 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306745 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6746 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006747 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6749 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306750 " TDLS Max peer already connected. Request declined."
6751 " Num of peers (%d), Max allowed (%d).",
6752 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6753 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006754 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006755 }
6756 else
6757 {
6758 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306759 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006760 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006761 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6763 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6764 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006765 return -EPERM;
6766 }
6767 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006768 if (0 == update)
6769 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006770
Jeff Johnsond75fe012013-04-06 10:53:06 -07006771 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306772 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006773 {
6774 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6775 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006776 if(StaParams->htcap_present)
6777 {
6778 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6779 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6780 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6781 "ht_capa->extended_capabilities: %0x",
6782 StaParams->HTCap.extendedHtCapInfo);
6783 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006784 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6785 "params->capability: %0x",StaParams->capability);
6786 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006787 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006788 if(StaParams->vhtcap_present)
6789 {
6790 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6791 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6792 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6793 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6794 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006795 {
6796 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006798 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6799 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6800 "[%d]: %x ", i, StaParams->supported_rates[i]);
6801 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006802 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306803 else if ((1 == update) && (NULL == StaParams))
6804 {
6805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6806 "%s : update is true, but staParams is NULL. Error!", __func__);
6807 return -EPERM;
6808 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006809
6810 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6811
6812 if (!update)
6813 {
6814 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6815 pAdapter->sessionId, mac);
6816 }
6817 else
6818 {
6819 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6820 pAdapter->sessionId, mac, StaParams);
6821 }
6822
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306823 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006824 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6825
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306826 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006827 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306829 "%s: timeout waiting for tdls add station indication %ld",
6830 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006831 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006832 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306833
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006834 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6835 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006837 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006838 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006839 }
6840
6841 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006842
6843error:
6844 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6845 return -EPERM;
6846
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006847}
6848#endif
6849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850static int wlan_hdd_change_station(struct wiphy *wiphy,
6851 struct net_device *dev,
6852 u8 *mac,
6853 struct station_parameters *params)
6854{
6855 VOS_STATUS status = VOS_STATUS_SUCCESS;
6856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306857 hdd_context_t *pHddCtx;
6858 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006860#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006861 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006862 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306863 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006864#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006865 ENTER();
6866
Gopichand Nakkala29149562013-05-10 21:43:41 +05306867 if ((NULL == pAdapter))
6868 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306870 "invalid adapter ");
6871 return -EINVAL;
6872 }
6873
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306874 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6875 TRACE_CODE_HDD_CHANGE_STATION,
6876 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306877 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6878 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6879
6880 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6881 {
6882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6883 "invalid HDD state or HDD station context");
6884 return -EINVAL;
6885 }
6886
6887 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888 {
6889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6890 "%s:LOGP in Progress. Ignore!!!", __func__);
6891 return -EAGAIN;
6892 }
6893
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6895
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006896 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6897 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006899 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 WLANTL_STA_AUTHENTICATED);
6903
Gopichand Nakkala29149562013-05-10 21:43:41 +05306904 if (status != VOS_STATUS_SUCCESS)
6905 {
6906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6907 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6908 return -EINVAL;
6909 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 }
6911 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006912 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6913 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306914#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006915 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6916 StaParams.capability = params->capability;
6917 StaParams.uapsd_queues = params->uapsd_queues;
6918 StaParams.max_sp = params->max_sp;
6919
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306920 /* Convert (first channel , number of channels) tuple to
6921 * the total list of channels. This goes with the assumption
6922 * that if the first channel is < 14, then the next channels
6923 * are an incremental of 1 else an incremental of 4 till the number
6924 * of channels.
6925 */
6926 if (0 != params->supported_channels_len) {
6927 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6928 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6929 {
6930 int wifi_chan_index;
6931 StaParams.supported_channels[j] = params->supported_channels[i];
6932 wifi_chan_index =
6933 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6934 no_of_channels = params->supported_channels[i+1];
6935 for(k=1; k <= no_of_channels; k++)
6936 {
6937 StaParams.supported_channels[j+1] =
6938 StaParams.supported_channels[j] + wifi_chan_index;
6939 j+=1;
6940 }
6941 }
6942 StaParams.supported_channels_len = j;
6943 }
6944 vos_mem_copy(StaParams.supported_oper_classes,
6945 params->supported_oper_classes,
6946 params->supported_oper_classes_len);
6947 StaParams.supported_oper_classes_len =
6948 params->supported_oper_classes_len;
6949
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006950 if (0 != params->ext_capab_len)
6951 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
6952 sizeof(StaParams.extn_capability));
6953
6954 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006955 {
6956 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006957 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006958 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006959
6960 StaParams.supported_rates_len = params->supported_rates_len;
6961
6962 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
6963 * The supported_rates array , for all the structures propogating till Add Sta
6964 * to the firmware has to be modified , if the supplicant (ieee80211) is
6965 * modified to send more rates.
6966 */
6967
6968 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
6969 */
6970 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
6971 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
6972
6973 if (0 != StaParams.supported_rates_len) {
6974 int i = 0;
6975 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
6976 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006978 "Supported Rates with Length %d", StaParams.supported_rates_len);
6979 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006981 "[%d]: %0x", i, StaParams.supported_rates[i]);
6982 }
6983
6984 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006985 {
6986 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006987 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006988 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006989
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006990 if (0 != params->ext_capab_len ) {
6991 /*Define A Macro : TODO Sunil*/
6992 if ((1<<4) & StaParams.extn_capability[3]) {
6993 isBufSta = 1;
6994 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306995 /* TDLS Channel Switching Support */
6996 if ((1<<6) & StaParams.extn_capability[3]) {
6997 isOffChannelSupported = 1;
6998 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006999 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307000 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7001 &StaParams, isBufSta,
7002 isOffChannelSupported);
7003
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307004 if (VOS_STATUS_SUCCESS != status) {
7005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7006 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7007 return -EINVAL;
7008 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007009 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7010
7011 if (VOS_STATUS_SUCCESS != status) {
7012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7013 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7014 return -EINVAL;
7015 }
7016 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007017#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307018 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007019 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 return status;
7021}
7022
7023/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307024 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 * This function is used to initialize the key information
7026 */
7027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307028static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 struct net_device *ndev,
7030 u8 key_index, bool pairwise,
7031 const u8 *mac_addr,
7032 struct key_params *params
7033 )
7034#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307035static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 struct net_device *ndev,
7037 u8 key_index, const u8 *mac_addr,
7038 struct key_params *params
7039 )
7040#endif
7041{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007042 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 tCsrRoamSetKey setKey;
7044 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307045 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007046 v_U32_t roamId= 0xFF;
7047 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 hdd_hostapd_state_t *pHostapdState;
7049 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007050 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307051 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007052
7053 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307054
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307055 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7056 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7057 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307058 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7059 status = wlan_hdd_validate_context(pHddCtx);
7060
7061 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007062 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7064 "%s: HDD context is not valid", __func__);
7065 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007066 }
7067
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7069 __func__, hdd_device_modetoString(pAdapter->device_mode),
7070 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007071
7072 if (CSR_MAX_NUM_KEY <= key_index)
7073 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 key_index);
7076
7077 return -EINVAL;
7078 }
7079
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007080 if (CSR_MAX_KEY_LEN < params->key_len)
7081 {
7082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7083 params->key_len);
7084
7085 return -EINVAL;
7086 }
7087
7088 hddLog(VOS_TRACE_LEVEL_INFO,
7089 "%s: called with key index = %d & key length %d",
7090 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007091
7092 /*extract key idx, key len and key*/
7093 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7094 setKey.keyId = key_index;
7095 setKey.keyLength = params->key_len;
7096 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7097
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007098 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 {
7100 case WLAN_CIPHER_SUITE_WEP40:
7101 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7102 break;
7103
7104 case WLAN_CIPHER_SUITE_WEP104:
7105 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7106 break;
7107
7108 case WLAN_CIPHER_SUITE_TKIP:
7109 {
7110 u8 *pKey = &setKey.Key[0];
7111 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7112
7113 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7114
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007115 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007116
7117 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007118 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 |--------------|----------|----------|
7120 <---16bytes---><--8bytes--><--8bytes-->
7121
7122 */
7123 /*Sme expects the 32 bytes key to be in the below order
7124
7125 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007126 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 |--------------|----------|----------|
7128 <---16bytes---><--8bytes--><--8bytes-->
7129 */
7130 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007131 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007132
7133 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007134 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135
7136 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007137 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007138
7139
7140 break;
7141 }
7142
7143 case WLAN_CIPHER_SUITE_CCMP:
7144 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7145 break;
7146
7147#ifdef FEATURE_WLAN_WAPI
7148 case WLAN_CIPHER_SUITE_SMS4:
7149 {
7150 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7151 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7152 params->key, params->key_len);
7153 return 0;
7154 }
7155#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007156
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007157#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 case WLAN_CIPHER_SUITE_KRK:
7159 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7160 break;
7161#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007162
7163#ifdef WLAN_FEATURE_11W
7164 case WLAN_CIPHER_SUITE_AES_CMAC:
7165 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007166 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007167#endif
7168
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 __func__, params->cipher);
7172 return -EOPNOTSUPP;
7173 }
7174
7175 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7176 __func__, setKey.encType);
7177
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007178 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007179#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7180 (!pairwise)
7181#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007182 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007183#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007184 )
7185 {
7186 /* set group key*/
7187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7188 "%s- %d: setting Broadcast key",
7189 __func__, __LINE__);
7190 setKey.keyDirection = eSIR_RX_ONLY;
7191 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7192 }
7193 else
7194 {
7195 /* set pairwise key*/
7196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7197 "%s- %d: setting pairwise key",
7198 __func__, __LINE__);
7199 setKey.keyDirection = eSIR_TX_RX;
7200 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7201 }
7202 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7203 {
7204 setKey.keyDirection = eSIR_TX_RX;
7205 /*Set the group key*/
7206 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7207 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007208
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007209 if ( 0 != status )
7210 {
7211 hddLog(VOS_TRACE_LEVEL_ERROR,
7212 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7213 return -EINVAL;
7214 }
7215 /*Save the keys here and call sme_RoamSetKey for setting
7216 the PTK after peer joins the IBSS network*/
7217 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7218 &setKey, sizeof(tCsrRoamSetKey));
7219 return status;
7220 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307221 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7222 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7223 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007225 if( pHostapdState->bssState == BSS_START )
7226 {
c_hpothu7c55da62014-01-23 18:34:02 +05307227 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7228 vos_status = wlan_hdd_check_ula_done(pAdapter);
7229
7230 if ( vos_status != VOS_STATUS_SUCCESS )
7231 {
7232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7233 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7234 __LINE__, vos_status );
7235
7236 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7237
7238 return -EINVAL;
7239 }
7240
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7242
7243 if ( status != eHAL_STATUS_SUCCESS )
7244 {
7245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7246 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7247 __LINE__, status );
7248 }
7249 }
7250
7251 /* Saving WEP keys */
7252 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7253 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7254 {
7255 //Save the wep key in ap context. Issue setkey after the BSS is started.
7256 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7257 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7258 }
7259 else
7260 {
7261 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007262 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7264 }
7265 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007266 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7267 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 {
7269 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7270 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7271
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7273 if (!pairwise)
7274#else
7275 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7276#endif
7277 {
7278 /* set group key*/
7279 if (pHddStaCtx->roam_info.deferKeyComplete)
7280 {
7281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7282 "%s- %d: Perform Set key Complete",
7283 __func__, __LINE__);
7284 hdd_PerformRoamSetKeyComplete(pAdapter);
7285 }
7286 }
7287
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7289
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007290 pWextState->roamProfile.Keys.defaultIndex = key_index;
7291
7292
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007293 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 params->key, params->key_len);
7295
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307296
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7298
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307299 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307301 __func__, setKey.peerMac[0], setKey.peerMac[1],
7302 setKey.peerMac[2], setKey.peerMac[3],
7303 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 setKey.keyDirection);
7305
7306 vos_status = wlan_hdd_check_ula_done(pAdapter);
7307
7308 if ( vos_status != VOS_STATUS_SUCCESS )
7309 {
7310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7311 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7312 __LINE__, vos_status );
7313
7314 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7315
7316 return -EINVAL;
7317
7318 }
7319
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007320#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307321 /* The supplicant may attempt to set the PTK once pre-authentication
7322 is done. Save the key in the UMAC and include it in the ADD BSS
7323 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007324 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307325 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007326 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307327 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7328 "%s: Update PreAuth Key success", __func__);
7329 return 0;
7330 }
7331 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7332 {
7333 hddLog(VOS_TRACE_LEVEL_ERROR,
7334 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307335 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007336 }
7337#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007338
7339 /* issue set key request to SME*/
7340 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7341 pAdapter->sessionId, &setKey, &roamId );
7342
7343 if ( 0 != status )
7344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307345 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7347 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7348 return -EINVAL;
7349 }
7350
7351
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307352 /* in case of IBSS as there was no information available about WEP keys during
7353 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307355 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7356 !( ( IW_AUTH_KEY_MGMT_802_1X
7357 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7359 )
7360 &&
7361 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7362 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7363 )
7364 )
7365 {
7366 setKey.keyDirection = eSIR_RX_ONLY;
7367 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7368
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307369 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307371 __func__, setKey.peerMac[0], setKey.peerMac[1],
7372 setKey.peerMac[2], setKey.peerMac[3],
7373 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 setKey.keyDirection);
7375
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307376 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 pAdapter->sessionId, &setKey, &roamId );
7378
7379 if ( 0 != status )
7380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307381 hddLog(VOS_TRACE_LEVEL_ERROR,
7382 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 __func__, status);
7384 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7385 return -EINVAL;
7386 }
7387 }
7388 }
7389
7390 return 0;
7391}
7392
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307393#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7394static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7395 struct net_device *ndev,
7396 u8 key_index, bool pairwise,
7397 const u8 *mac_addr,
7398 struct key_params *params
7399 )
7400#else
7401static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7402 struct net_device *ndev,
7403 u8 key_index, const u8 *mac_addr,
7404 struct key_params *params
7405 )
7406#endif
7407{
7408 int ret;
7409 vos_ssr_protect(__func__);
7410#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7411 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7412 mac_addr, params);
7413#else
7414 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7415 params);
7416#endif
7417 vos_ssr_unprotect(__func__);
7418
7419 return ret;
7420}
7421
Jeff Johnson295189b2012-06-20 16:38:30 -07007422/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307423 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 * This function is used to get the key information
7425 */
7426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307427static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307428 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307430 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 const u8 *mac_addr, void *cookie,
7432 void (*callback)(void *cookie, struct key_params*)
7433 )
7434#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307435static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007437 struct net_device *ndev,
7438 u8 key_index, const u8 *mac_addr, void *cookie,
7439 void (*callback)(void *cookie, struct key_params*)
7440 )
7441#endif
7442{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307443 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307444 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7445 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 struct key_params params;
7447
7448 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307449
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7451 __func__, hdd_device_modetoString(pAdapter->device_mode),
7452 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307453
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 memset(&params, 0, sizeof(params));
7455
7456 if (CSR_MAX_NUM_KEY <= key_index)
7457 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007461
7462 switch(pRoamProfile->EncryptionType.encryptionType[0])
7463 {
7464 case eCSR_ENCRYPT_TYPE_NONE:
7465 params.cipher = IW_AUTH_CIPHER_NONE;
7466 break;
7467
7468 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7469 case eCSR_ENCRYPT_TYPE_WEP40:
7470 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7471 break;
7472
7473 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7474 case eCSR_ENCRYPT_TYPE_WEP104:
7475 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7476 break;
7477
7478 case eCSR_ENCRYPT_TYPE_TKIP:
7479 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7480 break;
7481
7482 case eCSR_ENCRYPT_TYPE_AES:
7483 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7484 break;
7485
7486 default:
7487 params.cipher = IW_AUTH_CIPHER_NONE;
7488 break;
7489 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307490
c_hpothuaaf19692014-05-17 17:01:48 +05307491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7492 TRACE_CODE_HDD_CFG80211_GET_KEY,
7493 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307494
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7496 params.seq_len = 0;
7497 params.seq = NULL;
7498 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7499 callback(cookie, &params);
7500 return 0;
7501}
7502
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7504static int wlan_hdd_cfg80211_get_key(
7505 struct wiphy *wiphy,
7506 struct net_device *ndev,
7507 u8 key_index, bool pairwise,
7508 const u8 *mac_addr, void *cookie,
7509 void (*callback)(void *cookie, struct key_params*)
7510 )
7511#else
7512static int wlan_hdd_cfg80211_get_key(
7513 struct wiphy *wiphy,
7514 struct net_device *ndev,
7515 u8 key_index, const u8 *mac_addr, void *cookie,
7516 void (*callback)(void *cookie, struct key_params*)
7517 )
7518#endif
7519{
7520 int ret;
7521
7522 vos_ssr_protect(__func__);
7523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7524 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7525 mac_addr, cookie, callback);
7526#else
7527 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7528 callback);
7529#endif
7530 vos_ssr_unprotect(__func__);
7531
7532 return ret;
7533}
7534
Jeff Johnson295189b2012-06-20 16:38:30 -07007535/*
7536 * FUNCTION: wlan_hdd_cfg80211_del_key
7537 * This function is used to delete the key information
7538 */
7539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307540static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307542 u8 key_index,
7543 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 const u8 *mac_addr
7545 )
7546#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307547static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 struct net_device *ndev,
7549 u8 key_index,
7550 const u8 *mac_addr
7551 )
7552#endif
7553{
7554 int status = 0;
7555
7556 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307557 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007558 //it is observed that this is invalidating peer
7559 //key index whenever re-key is done. This is affecting data link.
7560 //It should be ok to ignore del_key.
7561#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7563 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7565 tCsrRoamSetKey setKey;
7566 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307567
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 ENTER();
7569
7570 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7571 __func__,pAdapter->device_mode);
7572
7573 if (CSR_MAX_NUM_KEY <= key_index)
7574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 key_index);
7577
7578 return -EINVAL;
7579 }
7580
7581 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7582 setKey.keyId = key_index;
7583
7584 if (mac_addr)
7585 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7586 else
7587 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7588
7589 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7590
7591 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307593 )
7594 {
7595
7596 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7598 if( pHostapdState->bssState == BSS_START)
7599 {
7600 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307601
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 if ( status != eHAL_STATUS_SUCCESS )
7603 {
7604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7605 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7606 __LINE__, status );
7607 }
7608 }
7609 }
7610 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307611 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007612 )
7613 {
7614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7615
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307616 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7617
7618 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307620 __func__, setKey.peerMac[0], setKey.peerMac[1],
7621 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 if(pAdapter->sessionCtx.station.conn_info.connState ==
7624 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307626 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 if ( 0 != status )
7630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307631 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 "%s: sme_RoamSetKey failure, returned %d",
7633 __func__, status);
7634 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7635 return -EINVAL;
7636 }
7637 }
7638 }
7639#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007640 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007641 return status;
7642}
7643
7644/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307645 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 * This function is used to set the default tx key index
7647 */
7648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307649static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 struct net_device *ndev,
7651 u8 key_index,
7652 bool unicast, bool multicast)
7653#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307654static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 struct net_device *ndev,
7656 u8 key_index)
7657#endif
7658{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307660 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307661 hdd_wext_state_t *pWextState;
7662 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307663 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007664
7665 ENTER();
7666
Gopichand Nakkala29149562013-05-10 21:43:41 +05307667 if ((NULL == pAdapter))
7668 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307670 "invalid adapter");
7671 return -EINVAL;
7672 }
7673
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307674 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7675 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7676 pAdapter->sessionId, key_index));
7677
Gopichand Nakkala29149562013-05-10 21:43:41 +05307678 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7679 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7680
7681 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7682 {
7683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7684 "invalid Wext state or HDD context");
7685 return -EINVAL;
7686 }
7687
Arif Hussain6d2a3322013-11-17 19:50:10 -08007688 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307690
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 if (CSR_MAX_NUM_KEY <= key_index)
7692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 key_index);
7695
7696 return -EINVAL;
7697 }
7698
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7700 status = wlan_hdd_validate_context(pHddCtx);
7701
7702 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007703 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7705 "%s: HDD context is not valid", __func__);
7706 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007707 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307708
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307711 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307713 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007714 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307715 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007716 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307718 {
7719 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007720 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307721
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 tCsrRoamSetKey setKey;
7723 v_U32_t roamId= 0xFF;
7724 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307725
7726 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307728
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 Keys->defaultIndex = (u8)key_index;
7730 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7731 setKey.keyId = key_index;
7732 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733
7734 vos_mem_copy(&setKey.Key[0],
7735 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307737
Gopichand Nakkala29149562013-05-10 21:43:41 +05307738 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307739
7740 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 &pHddStaCtx->conn_info.bssId[0],
7742 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307743
Gopichand Nakkala29149562013-05-10 21:43:41 +05307744 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7745 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7746 eCSR_ENCRYPT_TYPE_WEP104)
7747 {
7748 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7749 even though ap is configured for WEP-40 encryption. In this canse the key length
7750 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7751 type(104) and switching encryption type to 40*/
7752 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7753 eCSR_ENCRYPT_TYPE_WEP40;
7754 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7755 eCSR_ENCRYPT_TYPE_WEP40;
7756 }
7757
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307758 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307760
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307762 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307764
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 if ( 0 != status )
7766 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307767 hddLog(VOS_TRACE_LEVEL_ERROR,
7768 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 status);
7770 return -EINVAL;
7771 }
7772 }
7773 }
7774
7775 /* In SoftAp mode setting key direction for default mode */
7776 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7777 {
7778 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7779 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7780 (eCSR_ENCRYPT_TYPE_AES !=
7781 pWextState->roamProfile.EncryptionType.encryptionType[0])
7782 )
7783 {
7784 /* Saving key direction for default key index to TX default */
7785 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7786 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7787 }
7788 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 return status;
7791}
7792
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7794static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7795 struct net_device *ndev,
7796 u8 key_index,
7797 bool unicast, bool multicast)
7798#else
7799static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7800 struct net_device *ndev,
7801 u8 key_index)
7802#endif
7803{
7804 int ret;
7805 vos_ssr_protect(__func__);
7806#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7807 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7808 multicast);
7809#else
7810 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7811#endif
7812 vos_ssr_unprotect(__func__);
7813
7814 return ret;
7815}
7816
Jeff Johnson295189b2012-06-20 16:38:30 -07007817/*
7818 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7819 * This function is used to inform the BSS details to nl80211 interface.
7820 */
7821static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7822 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7823{
7824 struct net_device *dev = pAdapter->dev;
7825 struct wireless_dev *wdev = dev->ieee80211_ptr;
7826 struct wiphy *wiphy = wdev->wiphy;
7827 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7828 int chan_no;
7829 int ie_length;
7830 const char *ie;
7831 unsigned int freq;
7832 struct ieee80211_channel *chan;
7833 int rssi = 0;
7834 struct cfg80211_bss *bss = NULL;
7835
7836 ENTER();
7837
7838 if( NULL == pBssDesc )
7839 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007840 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 return bss;
7842 }
7843
7844 chan_no = pBssDesc->channelId;
7845 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7846 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7847
7848 if( NULL == ie )
7849 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007850 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 return bss;
7852 }
7853
7854#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7855 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7856 {
7857 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7858 }
7859 else
7860 {
7861 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7862 }
7863#else
7864 freq = ieee80211_channel_to_frequency(chan_no);
7865#endif
7866
7867 chan = __ieee80211_get_channel(wiphy, freq);
7868
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307869 if (!chan) {
7870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7871 return NULL;
7872 }
7873
Abhishek Singhaee43942014-06-16 18:55:47 +05307874 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007875
Abhishek Singhaee43942014-06-16 18:55:47 +05307876 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307877 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 pBssDesc->capabilityInfo,
7879 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307880 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007881}
7882
7883
7884
7885/*
7886 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7887 * This function is used to inform the BSS details to nl80211 interface.
7888 */
7889struct cfg80211_bss*
7890wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7891 tSirBssDescription *bss_desc
7892 )
7893{
7894 /*
7895 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7896 already exists in bss data base of cfg80211 for that particular BSS ID.
7897 Using cfg80211_inform_bss_frame to update the bss entry instead of
7898 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7899 now there is no possibility to get the mgmt(probe response) frame from PE,
7900 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7901 cfg80211_inform_bss_frame.
7902 */
7903 struct net_device *dev = pAdapter->dev;
7904 struct wireless_dev *wdev = dev->ieee80211_ptr;
7905 struct wiphy *wiphy = wdev->wiphy;
7906 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007907#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7908 qcom_ie_age *qie_age = NULL;
7909 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7910#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007911 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007912#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 const char *ie =
7914 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7915 unsigned int freq;
7916 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307917 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 struct cfg80211_bss *bss_status = NULL;
7919 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7920 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007921 hdd_context_t *pHddCtx;
7922 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007923#ifdef WLAN_OPEN_SOURCE
7924 struct timespec ts;
7925#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007926
Wilson Yangf80a0542013-10-07 13:02:37 -07007927 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7928 status = wlan_hdd_validate_context(pHddCtx);
7929
7930 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307931 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007932 {
7933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7934 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7935 return NULL;
7936 }
7937
7938
7939 if (0 != status)
7940 {
7941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7942 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007943 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007944 }
7945
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307946 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007947 if (!mgmt)
7948 {
7949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7950 "%s: memory allocation failed ", __func__);
7951 return NULL;
7952 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007953
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07007955
7956#ifdef WLAN_OPEN_SOURCE
7957 /* Android does not want the timestamp from the frame.
7958 Instead it wants a monotonic increasing value */
7959 get_monotonic_boottime(&ts);
7960 mgmt->u.probe_resp.timestamp =
7961 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
7962#else
7963 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
7965 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07007966
7967#endif
7968
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
7970 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007971
7972#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7973 /* GPS Requirement: need age ie per entry. Using vendor specific. */
7974 /* Assuming this is the last IE, copy at the end */
7975 ie_length -=sizeof(qcom_ie_age);
7976 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
7977 qie_age->element_id = QCOM_VENDOR_IE_ID;
7978 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
7979 qie_age->oui_1 = QCOM_OUI1;
7980 qie_age->oui_2 = QCOM_OUI2;
7981 qie_age->oui_3 = QCOM_OUI3;
7982 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
7983 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
7984#endif
7985
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05307987 if (bss_desc->fProbeRsp)
7988 {
7989 mgmt->frame_control |=
7990 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
7991 }
7992 else
7993 {
7994 mgmt->frame_control |=
7995 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
7996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007997
7998#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307999 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8001 {
8002 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8003 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8006
8007 {
8008 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8009 }
8010 else
8011 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8013 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 kfree(mgmt);
8015 return NULL;
8016 }
8017#else
8018 freq = ieee80211_channel_to_frequency(chan_no);
8019#endif
8020 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008021 /*when the band is changed on the fly using the GUI, three things are done
8022 * 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)
8023 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8024 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8025 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8026 * and discards the channels correponding to previous band and calls back with zero bss results.
8027 * 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
8028 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8029 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8030 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8031 * So drop the bss and continue to next bss.
8032 */
8033 if(chan == NULL)
8034 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008036 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008037 return NULL;
8038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308040 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 * */
8042 if (( eConnectionState_Associated ==
8043 pAdapter->sessionCtx.station.conn_info.connState ) &&
8044 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8045 pAdapter->sessionCtx.station.conn_info.bssId,
8046 WNI_CFG_BSSID_LEN)))
8047 {
8048 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8049 rssi = (pAdapter->rssi * 100);
8050 }
8051 else
8052 {
8053 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8054 }
8055
Nirav Shah20ac06f2013-12-12 18:14:06 +05308056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8057 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8058 chan->center_freq, (int)(rssi/100));
8059
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8061 frame_len, rssi, GFP_KERNEL);
8062 kfree(mgmt);
8063 return bss_status;
8064}
8065
8066/*
8067 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8068 * This function is used to update the BSS data base of CFG8011
8069 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308070struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 tCsrRoamInfo *pRoamInfo
8072 )
8073{
8074 tCsrRoamConnectedProfile roamProfile;
8075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8076 struct cfg80211_bss *bss = NULL;
8077
8078 ENTER();
8079
8080 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8081 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8082
8083 if (NULL != roamProfile.pBssDesc)
8084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 &roamProfile);
8087
8088 if (NULL == bss)
8089 {
8090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8091 __func__);
8092 }
8093
8094 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8095 }
8096 else
8097 {
8098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8099 __func__);
8100 }
8101 return bss;
8102}
8103
8104/*
8105 * FUNCTION: wlan_hdd_cfg80211_update_bss
8106 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308107static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8108 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308110{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308111 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 tCsrScanResultInfo *pScanResult;
8113 eHalStatus status = 0;
8114 tScanResultHandle pResult;
8115 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008116 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117
8118 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308119
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8121 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8122 NO_SESSION, pAdapter->sessionId));
8123
Wilson Yangf80a0542013-10-07 13:02:37 -07008124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8125
8126 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8129 "%s:LOGP in Progress. Ignore!!!",__func__);
8130 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 }
8132
Wilson Yangf80a0542013-10-07 13:02:37 -07008133
8134 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308135 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008136 {
8137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8138 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8139 return VOS_STATUS_E_PERM;
8140 }
8141
8142
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 /*
8144 * start getting scan results and populate cgf80211 BSS database
8145 */
8146 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8147
8148 /* no scan results */
8149 if (NULL == pResult)
8150 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8152 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 return status;
8154 }
8155
8156 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8157
8158 while (pScanResult)
8159 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308160 /*
8161 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8162 * entry already exists in bss data base of cfg80211 for that
8163 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8164 * bss entry instead of cfg80211_inform_bss, But this call expects
8165 * mgmt packet as input. As of now there is no possibility to get
8166 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 * ieee80211_mgmt(probe response) and passing to c
8168 * fg80211_inform_bss_frame.
8169 * */
8170
8171 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8172 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308173
Jeff Johnson295189b2012-06-20 16:38:30 -07008174
8175 if (NULL == bss_status)
8176 {
8177 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008178 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 }
8180 else
8181 {
Yue Maf49ba872013-08-19 12:04:25 -07008182 cfg80211_put_bss(
8183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8184 wiphy,
8185#endif
8186 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 }
8188
8189 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8190 }
8191
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308192 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008193
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308194 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008195}
8196
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008197void
8198hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8199{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308200 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008201 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008202} /****** end hddPrintMacAddr() ******/
8203
8204void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008205hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008206{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308207 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008208 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008209 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8210 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8211 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008212} /****** end hddPrintPmkId() ******/
8213
8214//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8215//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8216
8217//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8218//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8219
8220#define dump_bssid(bssid) \
8221 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008222 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8223 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008224 }
8225
8226#define dump_pmkid(pMac, pmkid) \
8227 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008228 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8229 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008230 }
8231
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008232#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008233/*
8234 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8235 * This function is used to notify the supplicant of a new PMKSA candidate.
8236 */
8237int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008239 int index, bool preauth )
8240{
Jeff Johnsone7245742012-09-05 17:12:55 -07008241#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008242 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008243 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008244
8245 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008246 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008247
8248 if( NULL == pRoamInfo )
8249 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008250 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008251 return -EINVAL;
8252 }
8253
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008254 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8255 {
8256 dump_bssid(pRoamInfo->bssid);
8257 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008258 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008259 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008260#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308261 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008262}
8263#endif //FEATURE_WLAN_LFR
8264
Yue Maef608272013-04-08 23:09:17 -07008265#ifdef FEATURE_WLAN_LFR_METRICS
8266/*
8267 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8268 * 802.11r/LFR metrics reporting function to report preauth initiation
8269 *
8270 */
8271#define MAX_LFR_METRICS_EVENT_LENGTH 100
8272VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8273 tCsrRoamInfo *pRoamInfo)
8274{
8275 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8276 union iwreq_data wrqu;
8277
8278 ENTER();
8279
8280 if (NULL == pAdapter)
8281 {
8282 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8283 return VOS_STATUS_E_FAILURE;
8284 }
8285
8286 /* create the event */
8287 memset(&wrqu, 0, sizeof(wrqu));
8288 memset(metrics_notification, 0, sizeof(metrics_notification));
8289
8290 wrqu.data.pointer = metrics_notification;
8291 wrqu.data.length = scnprintf(metrics_notification,
8292 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8293 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8294
8295 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8296
8297 EXIT();
8298
8299 return VOS_STATUS_SUCCESS;
8300}
8301
8302/*
8303 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8304 * 802.11r/LFR metrics reporting function to report preauth completion
8305 * or failure
8306 */
8307VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8308 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8309{
8310 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8311 union iwreq_data wrqu;
8312
8313 ENTER();
8314
8315 if (NULL == pAdapter)
8316 {
8317 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8318 return VOS_STATUS_E_FAILURE;
8319 }
8320
8321 /* create the event */
8322 memset(&wrqu, 0, sizeof(wrqu));
8323 memset(metrics_notification, 0, sizeof(metrics_notification));
8324
8325 scnprintf(metrics_notification, sizeof(metrics_notification),
8326 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8327 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8328
8329 if (1 == preauth_status)
8330 strncat(metrics_notification, " TRUE", 5);
8331 else
8332 strncat(metrics_notification, " FALSE", 6);
8333
8334 wrqu.data.pointer = metrics_notification;
8335 wrqu.data.length = strlen(metrics_notification);
8336
8337 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8338
8339 EXIT();
8340
8341 return VOS_STATUS_SUCCESS;
8342}
8343
8344/*
8345 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8346 * 802.11r/LFR metrics reporting function to report handover initiation
8347 *
8348 */
8349VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8350 tCsrRoamInfo *pRoamInfo)
8351{
8352 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8353 union iwreq_data wrqu;
8354
8355 ENTER();
8356
8357 if (NULL == pAdapter)
8358 {
8359 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8360 return VOS_STATUS_E_FAILURE;
8361 }
8362
8363 /* create the event */
8364 memset(&wrqu, 0, sizeof(wrqu));
8365 memset(metrics_notification, 0, sizeof(metrics_notification));
8366
8367 wrqu.data.pointer = metrics_notification;
8368 wrqu.data.length = scnprintf(metrics_notification,
8369 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8370 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8371
8372 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8373
8374 EXIT();
8375
8376 return VOS_STATUS_SUCCESS;
8377}
8378#endif
8379
Jeff Johnson295189b2012-06-20 16:38:30 -07008380/*
8381 * FUNCTION: hdd_cfg80211_scan_done_callback
8382 * scanning callback function, called after finishing scan
8383 *
8384 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308385static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008386 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8387{
8388 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308389 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008391 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8392 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 struct cfg80211_scan_request *req = NULL;
8394 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308395 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008397
8398 ENTER();
8399
8400 hddLog(VOS_TRACE_LEVEL_INFO,
8401 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008402 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 __func__, halHandle, pContext, (int) scanId, (int) status);
8404
Kiet Lamac06e2c2013-10-23 16:25:07 +05308405 pScanInfo->mScanPendingCounter = 0;
8406
Jeff Johnson295189b2012-06-20 16:38:30 -07008407 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308408 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 &pScanInfo->scan_req_completion_event,
8410 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308411 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308413 hddLog(VOS_TRACE_LEVEL_ERROR,
8414 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008416 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 }
8418
Yue Maef608272013-04-08 23:09:17 -07008419 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 {
8421 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008422 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 }
8424
8425 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308426 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 {
8428 hddLog(VOS_TRACE_LEVEL_INFO,
8429 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008430 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 (int) scanId);
8432 }
8433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308434 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 pAdapter);
8436
8437 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008439
8440
8441 /* If any client wait scan result through WEXT
8442 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008443 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 {
8445 /* The other scan request waiting for current scan finish
8446 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008447 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008449 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 }
8451 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008452 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 {
8454 struct net_device *dev = pAdapter->dev;
8455 union iwreq_data wrqu;
8456 int we_event;
8457 char *msg;
8458
8459 memset(&wrqu, '\0', sizeof(wrqu));
8460 we_event = SIOCGIWSCAN;
8461 msg = NULL;
8462 wireless_send_event(dev, we_event, &wrqu, msg);
8463 }
8464 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008465 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008466
8467 /* Get the Scan Req */
8468 req = pAdapter->request;
8469
8470 if (!req)
8471 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008472 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008473 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008474 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 }
8476
8477 /*
8478 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 req->n_ssids = 0;
8481 req->n_channels = 0;
8482 req->ie = 0;
8483
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008485 /* Scan is no longer pending */
8486 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008487
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008488 /*
8489 * cfg80211_scan_done informing NL80211 about completion
8490 * of scanning
8491 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308492 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8493 {
8494 aborted = true;
8495 }
8496 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008497 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008498
Jeff Johnsone7245742012-09-05 17:12:55 -07008499allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008500 /* release the wake lock at the end of the scan*/
8501 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008502
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008503 /* Acquire wakelock to handle the case where APP's tries to suspend
8504 * immediatly after the driver gets connect request(i.e after scan)
8505 * from supplicant, this result in app's is suspending and not able
8506 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308507 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008508
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008509#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308510 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8511 {
8512 wlan_hdd_tdls_scan_done_callback(pAdapter);
8513 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008514#endif
8515
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 EXIT();
8517 return 0;
8518}
8519
8520/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308521 * FUNCTION: hdd_isConnectionInProgress
8522 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008523 *
8524 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308525v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008526{
8527 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8528 hdd_station_ctx_t *pHddStaCtx = NULL;
8529 hdd_adapter_t *pAdapter = NULL;
8530 VOS_STATUS status = 0;
8531 v_U8_t staId = 0;
8532 v_U8_t *staMac = NULL;
8533
c_hpothu9b781ba2013-12-30 20:57:45 +05308534 if (TRUE == pHddCtx->btCoexModeSet)
8535 {
8536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308537 FL("BTCoex Mode operation in progress"));
8538 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308539 }
8540
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008541 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8542
8543 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8544 {
8545 pAdapter = pAdapterNode->pAdapter;
8546
8547 if( pAdapter )
8548 {
8549 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308550 "%s: Adapter with device mode %s (%d) exists",
8551 __func__, hdd_device_modetoString(pAdapter->device_mode),
8552 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308553 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8554 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8555 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8556 (eConnectionState_Connecting ==
8557 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8558 {
8559 hddLog(VOS_TRACE_LEVEL_ERROR,
8560 "%s: %p(%d) Connection is in progress", __func__,
8561 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8562 return VOS_TRUE;
8563 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008564 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308565 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8566 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008567 {
8568 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8569 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308570 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008571 {
8572 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8573 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008574 "%s: client " MAC_ADDRESS_STR
8575 " is in the middle of WPS/EAPOL exchange.", __func__,
8576 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308577 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008578 }
8579 }
8580 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8581 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8582 {
8583 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308585 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008586 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8587 {
8588 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8589
8590 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008591 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8592 "middle of WPS/EAPOL exchange.", __func__,
8593 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308594 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008595 }
8596 }
8597 }
8598 }
8599 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8600 pAdapterNode = pNext;
8601 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308602 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308603}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008604
8605/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308606 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 * this scan respond to scan trigger and update cfg80211 scan database
8608 * later, scan dump command can be used to recieve scan results
8609 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308610int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008611#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8612 struct net_device *dev,
8613#endif
8614 struct cfg80211_scan_request *request)
8615{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308616 hdd_adapter_t *pAdapter = NULL;
8617 hdd_context_t *pHddCtx = NULL;
8618 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308619 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008620 tCsrScanRequest scanRequest;
8621 tANI_U8 *channelList = NULL, i;
8622 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308623 int status;
8624 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008626
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8628 struct net_device *dev = NULL;
8629 if (NULL == request)
8630 {
8631 hddLog(VOS_TRACE_LEVEL_ERROR,
8632 "%s: scan req param null", __func__);
8633 return -EINVAL;
8634 }
8635 dev = request->wdev->netdev;
8636#endif
8637
8638 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8639 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8640 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8641
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 ENTER();
8643
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308644
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8646 __func__, hdd_device_modetoString(pAdapter->device_mode),
8647 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308648
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308649 status = wlan_hdd_validate_context(pHddCtx);
8650
8651 if (0 != status)
8652 {
8653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8654 "%s: HDD context is not valid", __func__);
8655 return status;
8656 }
8657
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308658 if (NULL == pwextBuf)
8659 {
8660 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8661 __func__);
8662 return -EIO;
8663 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308664 cfg_param = pHddCtx->cfg_ini;
8665 pScanInfo = &pHddCtx->scan_info;
8666
Jeff Johnson295189b2012-06-20 16:38:30 -07008667#ifdef WLAN_BTAMP_FEATURE
8668 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008669 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008671 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008672 "%s: No scanning when AMP is on", __func__);
8673 return -EOPNOTSUPP;
8674 }
8675#endif
8676 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008677 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008679 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308680 "%s: Not scanning on device_mode = %s (%d)",
8681 __func__, hdd_device_modetoString(pAdapter->device_mode),
8682 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 return -EOPNOTSUPP;
8684 }
8685
8686 if (TRUE == pScanInfo->mScanPending)
8687 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308688 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8689 {
8690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8691 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008692 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 }
8694
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308695 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008696 //Channel and action frame is pending
8697 //Otherwise Cancel Remain On Channel and allow Scan
8698 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008699 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008700 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008702 return -EBUSY;
8703 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008704#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008705 /* if tdls disagree scan right now, return immediately.
8706 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8707 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8708 */
8709 status = wlan_hdd_tdls_scan_callback (pAdapter,
8710 wiphy,
8711#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8712 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008713#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008714 request);
8715 if(status <= 0)
8716 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308717 if(!status)
8718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8719 "scan rejected %d", __func__, status);
8720 else
8721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8722 __func__, status);
8723
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008724 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008725 }
8726#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008727
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8729 {
8730 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008731 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8735 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308736 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 "%s: MAX TM Level Scan not allowed", __func__);
8738 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308739 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 }
8741 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8742
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008743 /* Check if scan is allowed at this point of time.
8744 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308745 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008746 {
8747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8748 return -EBUSY;
8749 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308750
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8752
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308753 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8754 (int)request->n_ssids);
8755
8756 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8757 * Becasue of this, driver is assuming that this is not wildcard scan and so
8758 * is not aging out the scan results.
8759 */
8760 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308762 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308764
8765 if ((request->ssids) && (0 < request->n_ssids))
8766 {
8767 tCsrSSIDInfo *SsidInfo;
8768 int j;
8769 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8770 /* Allocate num_ssid tCsrSSIDInfo structure */
8771 SsidInfo = scanRequest.SSIDs.SSIDList =
8772 ( tCsrSSIDInfo *)vos_mem_malloc(
8773 request->n_ssids*sizeof(tCsrSSIDInfo));
8774
8775 if(NULL == scanRequest.SSIDs.SSIDList)
8776 {
8777 hddLog(VOS_TRACE_LEVEL_ERROR,
8778 "%s: memory alloc failed SSIDInfo buffer", __func__);
8779 return -ENOMEM;
8780 }
8781
8782 /* copy all the ssid's and their length */
8783 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8784 {
8785 /* get the ssid length */
8786 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8787 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8788 SsidInfo->SSID.length);
8789 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8790 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8791 j, SsidInfo->SSID.ssId);
8792 }
8793 /* set the scan type to active */
8794 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8795 }
8796 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008797 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308798 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8799 TRACE_CODE_HDD_CFG80211_SCAN,
8800 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 /* set the scan type to active */
8802 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008803 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308804 else
8805 {
8806 /*Set the scan type to default type, in this case it is ACTIVE*/
8807 scanRequest.scanType = pScanInfo->scan_mode;
8808 }
8809 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8810 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008811
8812 /* set BSSType to default type */
8813 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8814
8815 /*TODO: scan the requested channels only*/
8816
8817 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308818 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308820 hddLog(VOS_TRACE_LEVEL_WARN,
8821 "No of Scan Channels exceeded limit: %d", request->n_channels);
8822 request->n_channels = MAX_CHANNEL;
8823 }
8824
8825 hddLog(VOS_TRACE_LEVEL_INFO,
8826 "No of Scan Channels: %d", request->n_channels);
8827
8828
8829 if( request->n_channels )
8830 {
8831 char chList [(request->n_channels*5)+1];
8832 int len;
8833 channelList = vos_mem_malloc( request->n_channels );
8834 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308835 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308836 hddLog(VOS_TRACE_LEVEL_ERROR,
8837 "%s: memory alloc failed channelList", __func__);
8838 status = -ENOMEM;
8839 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308840 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308841
8842 for( i = 0, len = 0; i < request->n_channels ; i++ )
8843 {
8844 channelList[i] = request->channels[i]->hw_value;
8845 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8846 }
8847
Nirav Shah20ac06f2013-12-12 18:14:06 +05308848 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308849 "Channel-List: %s ", chList);
8850 }
c_hpothu53512302014-04-15 18:49:53 +05308851
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308852 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8853 scanRequest.ChannelInfo.ChannelList = channelList;
8854
8855 /* set requestType to full scan */
8856 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8857
8858 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8859 * search (Flush on both full scan and social scan but not on single
8860 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8861 */
8862
8863 /* Supplicant does single channel scan after 8-way handshake
8864 * and in that case driver shoudnt flush scan results. If
8865 * driver flushes the scan results here and unfortunately if
8866 * the AP doesnt respond to our probe req then association
8867 * fails which is not desired
8868 */
8869
8870 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8871 {
8872 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8873 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8874 pAdapter->sessionId );
8875 }
8876
8877 if( request->ie_len )
8878 {
8879 /* save this for future association (join requires this) */
8880 /*TODO: Array needs to be converted to dynamic allocation,
8881 * as multiple ie.s can be sent in cfg80211_scan_request structure
8882 * CR 597966
8883 */
8884 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8885 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8886 pScanInfo->scanAddIE.length = request->ie_len;
8887
8888 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8889 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8890 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308892 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308894 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8895 memcpy( pwextBuf->roamProfile.addIEScan,
8896 request->ie, request->ie_len);
8897 }
8898 else
8899 {
8900 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8901 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 }
8903
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308904 }
8905 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8906 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8907
8908 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8909 request->ie_len);
8910 if (pP2pIe != NULL)
8911 {
8912#ifdef WLAN_FEATURE_P2P_DEBUG
8913 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8914 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8915 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308916 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308917 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8918 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8919 "Go nego completed to Connection is started");
8920 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8921 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308922 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308923 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8924 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308926 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8927 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8928 "Disconnected state to Connection is started");
8929 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8930 "for 4way Handshake");
8931 }
8932#endif
8933
8934 /* no_cck will be set during p2p find to disable 11b rates */
8935 if(TRUE == request->no_cck)
8936 {
8937 hddLog(VOS_TRACE_LEVEL_INFO,
8938 "%s: This is a P2P Search", __func__);
8939 scanRequest.p2pSearch = 1;
8940
8941 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308942 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308943 /* set requestType to P2P Discovery */
8944 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8945 }
8946
8947 /*
8948 Skip Dfs Channel in case of P2P Search
8949 if it is set in ini file
8950 */
8951 if(cfg_param->skipDfsChnlInP2pSearch)
8952 {
8953 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308954 }
8955 else
8956 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308957 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008959
Agarwal Ashish4f616132013-12-30 23:32:50 +05308960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962 }
8963
8964 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
8965
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008966 /* acquire the wakelock to avoid the apps suspend during the scan. To
8967 * address the following issues.
8968 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
8969 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
8970 * for long time, this result in apps running at full power for long time.
8971 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
8972 * be stuck in full power because of resume BMPS
8973 */
8974 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008975
Nirav Shah20ac06f2013-12-12 18:14:06 +05308976 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8977 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308978 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
8979 scanRequest.requestType, scanRequest.scanType,
8980 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05308981 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
8982
Jeff Johnsone7245742012-09-05 17:12:55 -07008983 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 pAdapter->sessionId, &scanRequest, &scanId,
8985 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07008986
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 if (eHAL_STATUS_SUCCESS != status)
8988 {
8989 hddLog(VOS_TRACE_LEVEL_ERROR,
8990 "%s: sme_ScanRequest returned error %d", __func__, status);
8991 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07008992 if(eHAL_STATUS_RESOURCES == status)
8993 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
8995 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07008996 status = -EBUSY;
8997 } else {
8998 status = -EIO;
8999 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009000 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 goto free_mem;
9002 }
9003
9004 pScanInfo->mScanPending = TRUE;
9005 pAdapter->request = request;
9006 pScanInfo->scanId = scanId;
9007
9008 complete(&pScanInfo->scan_req_completion_event);
9009
9010free_mem:
9011 if( scanRequest.SSIDs.SSIDList )
9012 {
9013 vos_mem_free(scanRequest.SSIDs.SSIDList);
9014 }
9015
9016 if( channelList )
9017 vos_mem_free( channelList );
9018
9019 EXIT();
9020
9021 return status;
9022}
9023
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309024int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9025#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9026 struct net_device *dev,
9027#endif
9028 struct cfg80211_scan_request *request)
9029{
9030 int ret;
9031
9032 vos_ssr_protect(__func__);
9033 ret = __wlan_hdd_cfg80211_scan(wiphy,
9034#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9035 dev,
9036#endif
9037 request);
9038 vos_ssr_unprotect(__func__);
9039
9040 return ret;
9041}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009042
9043void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9044{
9045 v_U8_t iniDot11Mode =
9046 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9047 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9048
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309049 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9050 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009051 switch ( iniDot11Mode )
9052 {
9053 case eHDD_DOT11_MODE_AUTO:
9054 case eHDD_DOT11_MODE_11ac:
9055 case eHDD_DOT11_MODE_11ac_ONLY:
9056#ifdef WLAN_FEATURE_11AC
9057 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9058#else
9059 hddDot11Mode = eHDD_DOT11_MODE_11n;
9060#endif
9061 break;
9062 case eHDD_DOT11_MODE_11n:
9063 case eHDD_DOT11_MODE_11n_ONLY:
9064 hddDot11Mode = eHDD_DOT11_MODE_11n;
9065 break;
9066 default:
9067 hddDot11Mode = iniDot11Mode;
9068 break;
9069 }
9070 /* This call decides required channel bonding mode */
9071 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9072 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9073 operationChannel);
9074}
9075
Jeff Johnson295189b2012-06-20 16:38:30 -07009076/*
9077 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309078 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309080int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009081 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009082{
9083 int status = 0;
9084 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009085 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 v_U32_t roamId;
9087 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 eCsrAuthType RSNAuthType;
9089
9090 ENTER();
9091
9092 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9094
9095 status = wlan_hdd_validate_context(pHddCtx);
9096 if (status)
9097 {
9098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9099 "%s: HDD context is not valid!", __func__);
9100 return status;
9101 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309102
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9104 {
9105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9106 return -EINVAL;
9107 }
9108
9109 pRoamProfile = &pWextState->roamProfile;
9110
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309111 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009113 hdd_station_ctx_t *pHddStaCtx;
9114 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009115
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309116 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9118 {
9119 /*QoS not enabled in cfg file*/
9120 pRoamProfile->uapsd_mask = 0;
9121 }
9122 else
9123 {
9124 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309125 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9127 }
9128
9129 pRoamProfile->SSIDs.numOfSSIDs = 1;
9130 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9131 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309132 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9134 ssid, ssid_len);
9135
9136 if (bssid)
9137 {
9138 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9139 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9140 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309141 /* Save BSSID in seperate variable as well, as RoamProfile
9142 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 case of join failure we should send valid BSSID to supplicant
9144 */
9145 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9146 WNI_CFG_BSSID_LEN);
9147 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009148 else
9149 {
9150 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009152
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309153 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9154 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9156 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309157 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 /*set gen ie*/
9159 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9160 /*set auth*/
9161 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009163#ifdef FEATURE_WLAN_WAPI
9164 if (pAdapter->wapi_info.nWapiMode)
9165 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009166 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 switch (pAdapter->wapi_info.wapiAuthMode)
9168 {
9169 case WAPI_AUTH_MODE_PSK:
9170 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009171 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 pAdapter->wapi_info.wapiAuthMode);
9173 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9174 break;
9175 }
9176 case WAPI_AUTH_MODE_CERT:
9177 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009178 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 pAdapter->wapi_info.wapiAuthMode);
9180 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9181 break;
9182 }
9183 } // End of switch
9184 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9185 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9186 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009187 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009188 pRoamProfile->AuthType.numEntries = 1;
9189 pRoamProfile->EncryptionType.numEntries = 1;
9190 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9191 pRoamProfile->mcEncryptionType.numEntries = 1;
9192 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9193 }
9194 }
9195#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309196#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309197 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309198 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9199 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9200 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309201 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9202 sizeof (tSirGtkOffloadParams));
9203 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309204 }
9205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 pRoamProfile->csrPersona = pAdapter->device_mode;
9207
Jeff Johnson32d95a32012-09-10 13:15:23 -07009208 if( operatingChannel )
9209 {
9210 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9211 pRoamProfile->ChannelInfo.numOfChannels = 1;
9212 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009213 else
9214 {
9215 pRoamProfile->ChannelInfo.ChannelList = NULL;
9216 pRoamProfile->ChannelInfo.numOfChannels = 0;
9217 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009218 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9219 {
9220 hdd_select_cbmode(pAdapter,operatingChannel);
9221 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309222
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009223 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9224 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309225 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009226 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009227 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9228 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309229 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9230 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309231 {
9232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9233 "%s: Set HDD connState to eConnectionState_Connecting",
9234 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009235 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9236 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309237 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309238 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 pAdapter->sessionId, pRoamProfile, &roamId);
9240
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309241 if ((eHAL_STATUS_SUCCESS != status) &&
9242 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9243 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309244
9245 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9247 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9248 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309249 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009250 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309251 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009252
9253 pRoamProfile->ChannelInfo.ChannelList = NULL;
9254 pRoamProfile->ChannelInfo.numOfChannels = 0;
9255
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 }
9257 else
9258 {
9259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9260 return -EINVAL;
9261 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009262 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 return status;
9264}
9265
9266/*
9267 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9268 * This function is used to set the authentication type (OPEN/SHARED).
9269 *
9270 */
9271static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9272 enum nl80211_auth_type auth_type)
9273{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309274 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9276
9277 ENTER();
9278
9279 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309280 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309283 hddLog(VOS_TRACE_LEVEL_INFO,
9284 "%s: set authentication type to AUTOSWITCH", __func__);
9285 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9286 break;
9287
9288 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009289#ifdef WLAN_FEATURE_VOWIFI_11R
9290 case NL80211_AUTHTYPE_FT:
9291#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309292 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 "%s: set authentication type to OPEN", __func__);
9294 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9295 break;
9296
9297 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309298 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 "%s: set authentication type to SHARED", __func__);
9300 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9301 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009302#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309304 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 "%s: set authentication type to CCKM WPA", __func__);
9306 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9307 break;
9308#endif
9309
9310
9311 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309312 hddLog(VOS_TRACE_LEVEL_ERROR,
9313 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 auth_type);
9315 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9316 return -EINVAL;
9317 }
9318
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 pHddStaCtx->conn_info.authType;
9321 return 0;
9322}
9323
9324/*
9325 * FUNCTION: wlan_hdd_set_akm_suite
9326 * This function is used to set the key mgmt type(PSK/8021x).
9327 *
9328 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309329static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 u32 key_mgmt
9331 )
9332{
9333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9334 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309335
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 /*set key mgmt type*/
9337 switch(key_mgmt)
9338 {
9339 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309340#ifdef WLAN_FEATURE_VOWIFI_11R
9341 case WLAN_AKM_SUITE_FT_PSK:
9342#endif
9343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 __func__);
9345 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9346 break;
9347
9348 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309349#ifdef WLAN_FEATURE_VOWIFI_11R
9350 case WLAN_AKM_SUITE_FT_8021X:
9351#endif
9352 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 __func__);
9354 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9355 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009356#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009357#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9358#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9359 case WLAN_AKM_SUITE_CCKM:
9360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9361 __func__);
9362 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9363 break;
9364#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009365#ifndef WLAN_AKM_SUITE_OSEN
9366#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9367 case WLAN_AKM_SUITE_OSEN:
9368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9369 __func__);
9370 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9371 break;
9372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
9374 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 __func__, key_mgmt);
9377 return -EINVAL;
9378
9379 }
9380 return 0;
9381}
9382
9383/*
9384 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309385 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 * (NONE/WEP40/WEP104/TKIP/CCMP).
9387 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309388static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9389 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 bool ucast
9391 )
9392{
9393 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309394 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9396
9397 ENTER();
9398
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309399 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 __func__, cipher);
9403 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9404 }
9405 else
9406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309407
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309409 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 {
9411 case IW_AUTH_CIPHER_NONE:
9412 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9413 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309416 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309420 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309422
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 case WLAN_CIPHER_SUITE_TKIP:
9424 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9425 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309426
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 case WLAN_CIPHER_SUITE_CCMP:
9428 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9429 break;
9430#ifdef FEATURE_WLAN_WAPI
9431 case WLAN_CIPHER_SUITE_SMS4:
9432 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9433 break;
9434#endif
9435
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009436#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 case WLAN_CIPHER_SUITE_KRK:
9438 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9439 break;
9440#endif
9441 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 __func__, cipher);
9444 return -EOPNOTSUPP;
9445 }
9446 }
9447
9448 if (ucast)
9449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 __func__, encryptionType);
9452 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9453 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 encryptionType;
9456 }
9457 else
9458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 __func__, encryptionType);
9461 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9462 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9463 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9464 }
9465
9466 return 0;
9467}
9468
9469
9470/*
9471 * FUNCTION: wlan_hdd_cfg80211_set_ie
9472 * This function is used to parse WPA/RSN IE's.
9473 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309474int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9475 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 size_t ie_len
9477 )
9478{
9479 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9480 u8 *genie = ie;
9481 v_U16_t remLen = ie_len;
9482#ifdef FEATURE_WLAN_WAPI
9483 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9484 u16 *tmp;
9485 v_U16_t akmsuiteCount;
9486 int *akmlist;
9487#endif
9488 ENTER();
9489
9490 /* clear previous assocAddIE */
9491 pWextState->assocAddIE.length = 0;
9492 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009493 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009494
9495 while (remLen >= 2)
9496 {
9497 v_U16_t eLen = 0;
9498 v_U8_t elementId;
9499 elementId = *genie++;
9500 eLen = *genie++;
9501 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309502
Arif Hussain6d2a3322013-11-17 19:50:10 -08009503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309505
9506 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309508 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009509 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 -07009510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309511 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 "%s: Invalid WPA IE", __func__);
9513 return -EINVAL;
9514 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309515 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 {
9517 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309518 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309520
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9522 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009523 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9524 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 VOS_ASSERT(0);
9526 return -ENOMEM;
9527 }
9528 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9529 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9530 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9533 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9534 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9535 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9537 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9539 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9540 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9541 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9542 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9543 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309544 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309545 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 {
9547 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309548 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9552 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009553 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9554 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 VOS_ASSERT(0);
9556 return -ENOMEM;
9557 }
9558 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9559 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9560 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309561
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9563 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009565#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9567 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 /*Consider WFD IE, only for P2P Client */
9569 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9570 {
9571 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309574
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9576 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009577 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9578 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 VOS_ASSERT(0);
9580 return -ENOMEM;
9581 }
9582 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9583 // WPS IE + P2P IE + WFD IE
9584 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9585 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309586
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9588 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9589 }
9590#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009591 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009593 HS20_OUI_TYPE_SIZE)) )
9594 {
9595 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009597 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009598
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009599 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9600 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009601 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9602 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009603 VOS_ASSERT(0);
9604 return -ENOMEM;
9605 }
9606 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9607 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009608
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009609 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9610 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9611 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009612 /* Appending OSEN Information Element in Assiciation Request */
9613 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9614 OSEN_OUI_TYPE_SIZE)) )
9615 {
9616 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9617 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9618 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009619
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009620 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9621 {
9622 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9623 "Need bigger buffer space");
9624 VOS_ASSERT(0);
9625 return -ENOMEM;
9626 }
9627 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9628 pWextState->assocAddIE.length += eLen + 2;
9629
9630 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9631 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9632 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9633 }
9634
9635 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009636 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9637
9638 /* populating as ADDIE in beacon frames */
9639 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9640 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9641 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9642 {
9643 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9644 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9645 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9646 {
9647 hddLog(LOGE,
9648 "Coldn't pass "
9649 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9650 }
9651 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9652 else
9653 hddLog(LOGE,
9654 "Could not pass on "
9655 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9656
9657 /* IBSS mode doesn't contain params->proberesp_ies still
9658 beaconIE's need to be populated in probe response frames */
9659 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9660 {
9661 u16 rem_probe_resp_ie_len = eLen + 2;
9662 u8 probe_rsp_ie_len[3] = {0};
9663 u8 counter = 0;
9664
9665 /* Check Probe Resp Length if it is greater then 255 then
9666 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9667 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9668 not able Store More then 255 bytes into One Variable */
9669
9670 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9671 {
9672 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9673 {
9674 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9675 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9676 }
9677 else
9678 {
9679 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9680 rem_probe_resp_ie_len = 0;
9681 }
9682 }
9683
9684 rem_probe_resp_ie_len = 0;
9685
9686 if (probe_rsp_ie_len[0] > 0)
9687 {
9688 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9689 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9690 (tANI_U8*)(genie - 2),
9691 probe_rsp_ie_len[0], NULL,
9692 eANI_BOOLEAN_FALSE)
9693 == eHAL_STATUS_FAILURE)
9694 {
9695 hddLog(LOGE,
9696 "Could not pass"
9697 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9698 }
9699 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9700 }
9701
9702 if (probe_rsp_ie_len[1] > 0)
9703 {
9704 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9705 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9706 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9707 probe_rsp_ie_len[1], NULL,
9708 eANI_BOOLEAN_FALSE)
9709 == eHAL_STATUS_FAILURE)
9710 {
9711 hddLog(LOGE,
9712 "Could not pass"
9713 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9714 }
9715 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9716 }
9717
9718 if (probe_rsp_ie_len[2] > 0)
9719 {
9720 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9721 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9722 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9723 probe_rsp_ie_len[2], NULL,
9724 eANI_BOOLEAN_FALSE)
9725 == eHAL_STATUS_FAILURE)
9726 {
9727 hddLog(LOGE,
9728 "Could not pass"
9729 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9730 }
9731 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9732 }
9733
9734 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9735 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9736 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9737 {
9738 hddLog(LOGE,
9739 "Could not pass"
9740 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9741 }
9742 }
9743 else
9744 {
9745 // Reset WNI_CFG_PROBE_RSP Flags
9746 wlan_hdd_reset_prob_rspies(pAdapter);
9747
9748 hddLog(VOS_TRACE_LEVEL_INFO,
9749 "%s: No Probe Response IE received in set beacon",
9750 __func__);
9751 }
9752 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 break;
9754 case DOT11F_EID_RSN:
9755 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9756 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9757 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9758 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9759 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9760 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009761 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9762 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309763 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009764 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009766 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309767
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009768 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9769 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009770 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9771 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009772 VOS_ASSERT(0);
9773 return -ENOMEM;
9774 }
9775 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9776 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309777
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009778 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9779 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9780 break;
9781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009782#ifdef FEATURE_WLAN_WAPI
9783 case WLAN_EID_WAPI:
9784 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009785 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 pAdapter->wapi_info.nWapiMode);
9787 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309788 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 akmsuiteCount = WPA_GET_LE16(tmp);
9790 tmp = tmp + 1;
9791 akmlist = (int *)(tmp);
9792 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9793 {
9794 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9795 }
9796 else
9797 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009798 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 VOS_ASSERT(0);
9800 return -EINVAL;
9801 }
9802
9803 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9804 {
9805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009806 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309810 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009812 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9814 }
9815 break;
9816#endif
9817 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309818 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009820 /* when Unknown IE is received we should break and continue
9821 * to the next IE in the buffer instead we were returning
9822 * so changing this to break */
9823 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 }
9825 genie += eLen;
9826 remLen -= eLen;
9827 }
9828 EXIT();
9829 return 0;
9830}
9831
9832/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309833 * FUNCTION: hdd_isWPAIEPresent
9834 * Parse the received IE to find the WPA IE
9835 *
9836 */
9837static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9838{
9839 v_U8_t eLen = 0;
9840 v_U16_t remLen = ie_len;
9841 v_U8_t elementId = 0;
9842
9843 while (remLen >= 2)
9844 {
9845 elementId = *ie++;
9846 eLen = *ie++;
9847 remLen -= 2;
9848 if (eLen > remLen)
9849 {
9850 hddLog(VOS_TRACE_LEVEL_ERROR,
9851 "%s: IE length is wrong %d", __func__, eLen);
9852 return FALSE;
9853 }
9854 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9855 {
9856 /* OUI - 0x00 0X50 0XF2
9857 WPA Information Element - 0x01
9858 WPA version - 0x01*/
9859 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9860 return TRUE;
9861 }
9862 ie += eLen;
9863 remLen -= eLen;
9864 }
9865 return FALSE;
9866}
9867
9868/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309870 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 * parameters during connect operation.
9872 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309873int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 struct cfg80211_connect_params *req
9875 )
9876{
9877 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309878 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 ENTER();
9880
9881 /*set wpa version*/
9882 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9883
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309884 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309886 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 {
9888 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9889 }
9890 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9891 {
9892 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9893 }
9894 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309895
9896 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 pWextState->wpaVersion);
9898
9899 /*set authentication type*/
9900 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9901
9902 if (0 > status)
9903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309904 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 "%s: failed to set authentication type ", __func__);
9906 return status;
9907 }
9908
9909 /*set key mgmt type*/
9910 if (req->crypto.n_akm_suites)
9911 {
9912 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9913 if (0 > status)
9914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 __func__);
9917 return status;
9918 }
9919 }
9920
9921 /*set pairwise cipher type*/
9922 if (req->crypto.n_ciphers_pairwise)
9923 {
9924 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9925 req->crypto.ciphers_pairwise[0], true);
9926 if (0 > status)
9927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 "%s: failed to set unicast cipher type", __func__);
9930 return status;
9931 }
9932 }
9933 else
9934 {
9935 /*Reset previous cipher suite to none*/
9936 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9937 if (0 > status)
9938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309939 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 "%s: failed to set unicast cipher type", __func__);
9941 return status;
9942 }
9943 }
9944
9945 /*set group cipher type*/
9946 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9947 false);
9948
9949 if (0 > status)
9950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 __func__);
9953 return status;
9954 }
9955
Chet Lanctot186b5732013-03-18 10:26:30 -07009956#ifdef WLAN_FEATURE_11W
9957 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
9958#endif
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
9961 if (req->ie_len)
9962 {
9963 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
9964 if ( 0 > status)
9965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 __func__);
9968 return status;
9969 }
9970 }
9971
9972 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309973 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 {
9975 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
9976 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
9977 )
9978 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309979 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07009980 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
9981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 __func__);
9984 return -EOPNOTSUPP;
9985 }
9986 else
9987 {
9988 u8 key_len = req->key_len;
9989 u8 key_idx = req->key_idx;
9990
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309991 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 && (CSR_MAX_NUM_KEY > key_idx)
9993 )
9994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309995 hddLog(VOS_TRACE_LEVEL_INFO,
9996 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 __func__, key_idx, key_len);
9998 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309999 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010001 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 (u8)key_len;
10003 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10004 }
10005 }
10006 }
10007 }
10008
10009 return status;
10010}
10011
10012/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010013 * FUNCTION: wlan_hdd_try_disconnect
10014 * This function is used to disconnect from previous
10015 * connection
10016 */
10017static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10018{
10019 long ret = 0;
10020 hdd_station_ctx_t *pHddStaCtx;
10021 eMib_dot11DesiredBssType connectedBssType;
10022
10023 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10024
10025 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10026
10027 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10028 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10029 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10030 {
10031 /* Issue disconnect to CSR */
10032 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10033 if( eHAL_STATUS_SUCCESS ==
10034 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10035 pAdapter->sessionId,
10036 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10037 {
10038 ret = wait_for_completion_interruptible_timeout(
10039 &pAdapter->disconnect_comp_var,
10040 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10041 if (0 >= ret)
10042 {
10043 hddLog(LOGE, FL("Failed to receive disconnect event"));
10044 return -EALREADY;
10045 }
10046 }
10047 }
10048 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10049 {
10050 ret = wait_for_completion_interruptible_timeout(
10051 &pAdapter->disconnect_comp_var,
10052 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10053 if (0 >= ret)
10054 {
10055 hddLog(LOGE, FL("Failed to receive disconnect event"));
10056 return -EALREADY;
10057 }
10058 }
10059
10060 return 0;
10061}
10062
10063/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010064 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010065 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 * parameters during connect operation.
10067 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010068static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 struct net_device *ndev,
10070 struct cfg80211_connect_params *req
10071 )
10072{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010073 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010076 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077
10078 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10081 TRACE_CODE_HDD_CFG80211_CONNECT,
10082 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010083 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010084 "%s: device_mode = %s (%d)", __func__,
10085 hdd_device_modetoString(pAdapter->device_mode),
10086 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010087
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010089 if (!pHddCtx)
10090 {
10091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10092 "%s: HDD context is null", __func__);
10093 return VOS_STATUS_E_FAILURE;
10094 }
10095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010096 status = wlan_hdd_validate_context(pHddCtx);
10097
10098 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10101 "%s: HDD context is not valid", __func__);
10102 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 }
10104
10105#ifdef WLAN_BTAMP_FEATURE
10106 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010107 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010109 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010111 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 }
10113#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010114
10115 //If Device Mode is Station Concurrent Sessions Exit BMps
10116 //P2P Mode will be taken care in Open/close adapter
10117 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10118 (vos_concurrent_sessions_running()))
10119 {
10120 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10121 }
10122
10123 /*Try disconnecting if already in connected state*/
10124 status = wlan_hdd_try_disconnect(pAdapter);
10125 if ( 0 > status)
10126 {
10127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10128 " connection"));
10129 return -EALREADY;
10130 }
10131
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010133 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
10135 if ( 0 > status)
10136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 __func__);
10139 return status;
10140 }
10141
Mohit Khanna765234a2012-09-11 15:08:35 -070010142 if ( req->channel )
10143 {
10144 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10145 req->ssid_len, req->bssid,
10146 req->channel->hw_value);
10147 }
10148 else
10149 {
10150 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010151 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010152 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010153
10154 if (0 > status)
10155 {
10156 //ReEnable BMPS if disabled
10157 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10158 (NULL != pHddCtx))
10159 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010160 if (pHddCtx->hdd_wlan_suspended)
10161 {
10162 hdd_set_pwrparams(pHddCtx);
10163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010164 //ReEnable Bmps and Imps back
10165 hdd_enable_bmps_imps(pHddCtx);
10166 }
10167
10168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10169 return status;
10170 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010171 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 EXIT();
10173 return status;
10174}
10175
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010176static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10177 struct net_device *ndev,
10178 struct cfg80211_connect_params *req)
10179{
10180 int ret;
10181 vos_ssr_protect(__func__);
10182 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10183 vos_ssr_unprotect(__func__);
10184
10185 return ret;
10186}
Jeff Johnson295189b2012-06-20 16:38:30 -070010187
10188/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010189 * FUNCTION: wlan_hdd_disconnect
10190 * This function is used to issue a disconnect request to SME
10191 */
10192int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10193{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010194 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010195 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010196 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010197 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010198
10199 status = wlan_hdd_validate_context(pHddCtx);
10200
10201 if (0 != status)
10202 {
10203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10204 "%s: HDD context is not valid", __func__);
10205 return status;
10206 }
10207
10208 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10210 "%s: Set HDD connState to eConnectionState_Disconnecting",
10211 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010212 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010213 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010214
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010215 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010216
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010217 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10218 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010219 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10220 {
10221 hddLog(VOS_TRACE_LEVEL_INFO,
10222 FL("status = %d, already disconnected"),
10223 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010224
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010225 }
10226 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010227 {
10228 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010229 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010230 __func__, (int)status );
10231 return -EINVAL;
10232 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010233 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010234 &pAdapter->disconnect_comp_var,
10235 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010236 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010237 {
10238 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010239 "%s: Failed to disconnect, timed out", __func__);
10240 return -ETIMEDOUT;
10241 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010242 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010243 {
10244 hddLog(VOS_TRACE_LEVEL_ERROR,
10245 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010246 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010247 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10249 FL("Set HDD connState to eConnectionState_NotConnected"));
10250 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10251
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010252 /*stop tx queues*/
10253 netif_tx_disable(pAdapter->dev);
10254 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010255 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010256}
10257
10258
10259/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010260 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 * This function is used to issue a disconnect request to SME
10262 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010263static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 struct net_device *dev,
10265 u16 reason
10266 )
10267{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010269 tCsrRoamProfile *pRoamProfile =
10270 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010271 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010272 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10273 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010274#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010275 tANI_U8 staIdx;
10276#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010277
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010279
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10281 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10282 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010283 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10284 __func__, hdd_device_modetoString(pAdapter->device_mode),
10285 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010286
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010287 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10288 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010289
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010290 status = wlan_hdd_validate_context(pHddCtx);
10291
10292 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10295 "%s: HDD context is not valid", __func__);
10296 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010298
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 if (NULL != pRoamProfile)
10300 {
10301 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010302 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10303 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010305 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010307 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010308 switch(reason)
10309 {
10310 case WLAN_REASON_MIC_FAILURE:
10311 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10312 break;
10313
10314 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10315 case WLAN_REASON_DISASSOC_AP_BUSY:
10316 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10317 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10318 break;
10319
10320 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10321 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010322 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10324 break;
10325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 default:
10327 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10328 break;
10329 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010330 pScanInfo = &pHddCtx->scan_info;
10331 if (pScanInfo->mScanPending)
10332 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010333 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010334 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010335 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10336 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010337 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010338
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010339#ifdef FEATURE_WLAN_TDLS
10340 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010341 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010342 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010343 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10344 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010345 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010346 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010347 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010348 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010349 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010350 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010351 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010352 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010353 pAdapter->sessionId,
10354 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010355 }
10356 }
10357#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010358 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010359 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10360 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 {
10362 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010363 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 __func__, (int)status );
10365 return -EINVAL;
10366 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010368 else
10369 {
10370 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10371 "called while in %d state", __func__,
10372 pHddStaCtx->conn_info.connState);
10373 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 }
10375 else
10376 {
10377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10378 }
10379
10380 return status;
10381}
10382
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010383static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10384 struct net_device *dev,
10385 u16 reason
10386 )
10387{
10388 int ret;
10389 vos_ssr_protect(__func__);
10390 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10391 vos_ssr_unprotect(__func__);
10392
10393 return ret;
10394}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010395
Jeff Johnson295189b2012-06-20 16:38:30 -070010396/*
10397 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010398 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 * settings in IBSS mode.
10400 */
10401static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010402 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 struct cfg80211_ibss_params *params
10404 )
10405{
10406 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010407 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10409 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010410
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 ENTER();
10412
10413 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010414 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010415
10416 if (params->ie_len && ( NULL != params->ie) )
10417 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010418 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10419 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 {
10421 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10422 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10423 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010424 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010426 tDot11fIEWPA dot11WPAIE;
10427 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010428 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010429
Wilson Yang00256342013-10-10 23:13:38 -070010430 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010431 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10432 params->ie_len, DOT11F_EID_WPA);
10433 if ( NULL != ie )
10434 {
10435 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10436 // Unpack the WPA IE
10437 //Skip past the EID byte and length byte - and four byte WiFi OUI
10438 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10439 &ie[2+4],
10440 ie[1] - 4,
10441 &dot11WPAIE);
10442 /*Extract the multicast cipher, the encType for unicast
10443 cipher for wpa-none is none*/
10444 encryptionType =
10445 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10446 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010448
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10450
10451 if (0 > status)
10452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 __func__);
10455 return status;
10456 }
10457 }
10458
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010459 pWextState->roamProfile.AuthType.authType[0] =
10460 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10462
10463 if (params->privacy)
10464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010465 /* Security enabled IBSS, At this time there is no information available
10466 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010470 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 *enable privacy bit in beacons */
10472
10473 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10474 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010475 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10476 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10478 pWextState->roamProfile.EncryptionType.numEntries = 1;
10479 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 return status;
10481}
10482
10483/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010484 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010485 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010487static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 struct net_device *dev,
10489 struct cfg80211_ibss_params *params
10490 )
10491{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10494 tCsrRoamProfile *pRoamProfile;
10495 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010496 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010497 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10498 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499
10500 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10503 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10504 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010506 "%s: device_mode = %s (%d)", __func__,
10507 hdd_device_modetoString(pAdapter->device_mode),
10508 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010509
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010510 status = wlan_hdd_validate_context(pHddCtx);
10511
10512 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10515 "%s: HDD context is not valid", __func__);
10516 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 }
10518
10519 if (NULL == pWextState)
10520 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010521 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010522 __func__);
10523 return -EIO;
10524 }
10525
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010526 /*Try disconnecting if already in connected state*/
10527 status = wlan_hdd_try_disconnect(pAdapter);
10528 if ( 0 > status)
10529 {
10530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10531 " IBSS connection"));
10532 return -EALREADY;
10533 }
10534
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 pRoamProfile = &pWextState->roamProfile;
10536
10537 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10538 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010539 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010540 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 return -EINVAL;
10542 }
10543
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010544 /* BSSID is provided by upper layers hence no need to AUTO generate */
10545 if (NULL != params->bssid) {
10546 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10547 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10548 hddLog (VOS_TRACE_LEVEL_ERROR,
10549 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10550 return -EIO;
10551 }
10552 }
krunal sonie9002db2013-11-25 14:24:17 -080010553 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10554 {
10555 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10556 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10557 {
10558 hddLog (VOS_TRACE_LEVEL_ERROR,
10559 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10560 return -EIO;
10561 }
10562 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10563 if (!params->bssid)
10564 {
10565 hddLog (VOS_TRACE_LEVEL_ERROR,
10566 "%s:Failed memory allocation", __func__);
10567 return -EIO;
10568 }
10569 vos_mem_copy((v_U8_t *)params->bssid,
10570 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10571 VOS_MAC_ADDR_SIZE);
10572 alloc_bssid = VOS_TRUE;
10573 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010574
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010576 if (NULL !=
10577#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10578 params->chandef.chan)
10579#else
10580 params->channel)
10581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 {
10583 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010584 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10585 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10586 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10587 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010588
10589 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010591 ieee80211_frequency_to_channel(
10592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10593 params->chandef.chan->center_freq);
10594#else
10595 params->channel->center_freq);
10596#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010597
10598 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10599 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10602 __func__);
10603 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010605
10606 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010608 if (channelNum == validChan[indx])
10609 {
10610 break;
10611 }
10612 }
10613 if (indx >= numChans)
10614 {
10615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 __func__, channelNum);
10617 return -EINVAL;
10618 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010619 /* Set the Operational Channel */
10620 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10621 channelNum);
10622 pRoamProfile->ChannelInfo.numOfChannels = 1;
10623 pHddStaCtx->conn_info.operationChannel = channelNum;
10624 pRoamProfile->ChannelInfo.ChannelList =
10625 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010626 }
10627
10628 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010629 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 if (status < 0)
10631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 __func__);
10634 return status;
10635 }
10636
10637 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010639 params->ssid_len, params->bssid,
10640 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010641
10642 if (0 > status)
10643 {
10644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10645 return status;
10646 }
10647
krunal sonie9002db2013-11-25 14:24:17 -080010648 if (NULL != params->bssid &&
10649 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10650 alloc_bssid == VOS_TRUE)
10651 {
10652 vos_mem_free(params->bssid);
10653 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 return 0;
10655}
10656
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010657static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10658 struct net_device *dev,
10659 struct cfg80211_ibss_params *params
10660 )
10661{
10662 int ret = 0;
10663
10664 vos_ssr_protect(__func__);
10665 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10666 vos_ssr_unprotect(__func__);
10667
10668 return ret;
10669}
10670
Jeff Johnson295189b2012-06-20 16:38:30 -070010671/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010672 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010675static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 struct net_device *dev
10677 )
10678{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010680 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10681 tCsrRoamProfile *pRoamProfile;
10682 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010683 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010684
10685 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010686
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010687 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10688 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10689 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010690 status = wlan_hdd_validate_context(pHddCtx);
10691
10692 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010693 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10695 "%s: HDD context is not valid", __func__);
10696 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010697 }
10698
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10700 hdd_device_modetoString(pAdapter->device_mode),
10701 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 if (NULL == pWextState)
10703 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010704 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 __func__);
10706 return -EIO;
10707 }
10708
10709 pRoamProfile = &pWextState->roamProfile;
10710
10711 /* Issue disconnect only if interface type is set to IBSS */
10712 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010714 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 __func__);
10716 return -EINVAL;
10717 }
10718
10719 /* Issue Disconnect request */
10720 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10721 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10722 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10723
10724 return 0;
10725}
10726
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010727static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10728 struct net_device *dev
10729 )
10730{
10731 int ret = 0;
10732
10733 vos_ssr_protect(__func__);
10734 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10735 vos_ssr_unprotect(__func__);
10736
10737 return ret;
10738}
10739
Jeff Johnson295189b2012-06-20 16:38:30 -070010740/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010741 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 * This function is used to set the phy parameters
10743 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10744 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010745static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 u32 changed)
10747{
10748 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10749 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010750 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010751
10752 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010753 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10754 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10755 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010756 status = wlan_hdd_validate_context(pHddCtx);
10757
10758 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010759 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10761 "%s: HDD context is not valid", __func__);
10762 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010763 }
10764
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10766 {
10767 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10768 WNI_CFG_RTS_THRESHOLD_STAMAX :
10769 wiphy->rts_threshold;
10770
10771 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010774 hddLog(VOS_TRACE_LEVEL_ERROR,
10775 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 __func__, rts_threshold);
10777 return -EINVAL;
10778 }
10779
10780 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10781 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010782 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010784 hddLog(VOS_TRACE_LEVEL_ERROR,
10785 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 __func__, rts_threshold);
10787 return -EIO;
10788 }
10789
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010790 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 rts_threshold);
10792 }
10793
10794 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10795 {
10796 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10797 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10798 wiphy->frag_threshold;
10799
10800 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010801 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010803 hddLog(VOS_TRACE_LEVEL_ERROR,
10804 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 frag_threshold);
10806 return -EINVAL;
10807 }
10808
10809 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10810 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010811 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010813 hddLog(VOS_TRACE_LEVEL_ERROR,
10814 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 __func__, frag_threshold);
10816 return -EIO;
10817 }
10818
10819 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10820 frag_threshold);
10821 }
10822
10823 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10824 || (changed & WIPHY_PARAM_RETRY_LONG))
10825 {
10826 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10827 wiphy->retry_short :
10828 wiphy->retry_long;
10829
10830 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10831 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 __func__, retry_value);
10835 return -EINVAL;
10836 }
10837
10838 if (changed & WIPHY_PARAM_RETRY_SHORT)
10839 {
10840 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10841 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010842 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010844 hddLog(VOS_TRACE_LEVEL_ERROR,
10845 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010846 __func__, retry_value);
10847 return -EIO;
10848 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 __func__, retry_value);
10851 }
10852 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10853 {
10854 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10855 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010856 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010858 hddLog(VOS_TRACE_LEVEL_ERROR,
10859 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 __func__, retry_value);
10861 return -EIO;
10862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 __func__, retry_value);
10865 }
10866 }
10867
10868 return 0;
10869}
10870
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010871static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10872 u32 changed)
10873{
10874 int ret;
10875
10876 vos_ssr_protect(__func__);
10877 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10878 vos_ssr_unprotect(__func__);
10879
10880 return ret;
10881}
10882
Jeff Johnson295189b2012-06-20 16:38:30 -070010883/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010884 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 * This function is used to set the txpower
10886 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010887static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010888#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10889 struct wireless_dev *wdev,
10890#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010891#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010892 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010893#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010894 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010895#endif
10896 int dbm)
10897{
10898 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010899 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010900 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10901 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010902 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010903
10904 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10906 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10907 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010908 status = wlan_hdd_validate_context(pHddCtx);
10909
10910 if (0 != status)
10911 {
10912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10913 "%s: HDD context is not valid", __func__);
10914 return status;
10915 }
10916
10917 hHal = pHddCtx->hHal;
10918
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010919 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10920 dbm, ccmCfgSetCallback,
10921 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010923 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10925 return -EIO;
10926 }
10927
10928 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10929 dbm);
10930
10931 switch(type)
10932 {
10933 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
10934 /* Fall through */
10935 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
10936 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
10937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
10939 __func__);
10940 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 }
10942 break;
10943 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 __func__);
10946 return -EOPNOTSUPP;
10947 break;
10948 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
10950 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 return -EIO;
10952 }
10953
10954 return 0;
10955}
10956
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010957static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
10958#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10959 struct wireless_dev *wdev,
10960#endif
10961#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10962 enum tx_power_setting type,
10963#else
10964 enum nl80211_tx_power_setting type,
10965#endif
10966 int dbm)
10967{
10968 int ret;
10969 vos_ssr_protect(__func__);
10970 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
10971#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10972 wdev,
10973#endif
10974#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10975 type,
10976#else
10977 type,
10978#endif
10979 dbm);
10980 vos_ssr_unprotect(__func__);
10981
10982 return ret;
10983}
10984
Jeff Johnson295189b2012-06-20 16:38:30 -070010985/*
10986 * FUNCTION: wlan_hdd_cfg80211_get_txpower
10987 * This function is used to read the txpower
10988 */
Yue Maf49ba872013-08-19 12:04:25 -070010989static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
10990#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10991 struct wireless_dev *wdev,
10992#endif
10993 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070010994{
10995
10996 hdd_adapter_t *pAdapter;
10997 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010998 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010999
Jeff Johnsone7245742012-09-05 17:12:55 -070011000 ENTER();
11001
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011002 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011003
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011004 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011005 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11007 "%s: HDD context is not valid", __func__);
11008 *dbm = 0;
11009 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011010 }
11011
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11013 if (NULL == pAdapter)
11014 {
11015 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11016 return -ENOENT;
11017 }
11018
11019 wlan_hdd_get_classAstats(pAdapter);
11020 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11021
Jeff Johnsone7245742012-09-05 17:12:55 -070011022 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 return 0;
11024}
11025
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011026static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 u8* mac, struct station_info *sinfo)
11028{
11029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11030 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11031 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011032 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011033
11034 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11035 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011036
11037 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11038 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11039 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11040 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11041 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11042 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11043 tANI_U16 maxRate = 0;
11044 tANI_U16 myRate;
11045 tANI_U16 currentRate = 0;
11046 tANI_U8 maxSpeedMCS = 0;
11047 tANI_U8 maxMCSIdx = 0;
11048 tANI_U8 rateFlag = 1;
11049 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011050 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011051 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011052
Leo Chang6f8870f2013-03-26 18:11:36 -070011053#ifdef WLAN_FEATURE_11AC
11054 tANI_U32 vht_mcs_map;
11055 eDataRate11ACMaxMcs vhtMaxMcs;
11056#endif /* WLAN_FEATURE_11AC */
11057
Jeff Johnsone7245742012-09-05 17:12:55 -070011058 ENTER();
11059
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11061 (0 == ssidlen))
11062 {
11063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11064 " Invalid ssidlen, %d", __func__, ssidlen);
11065 /*To keep GUI happy*/
11066 return 0;
11067 }
11068
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011069 status = wlan_hdd_validate_context(pHddCtx);
11070
11071 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011072 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11074 "%s: HDD context is not valid", __func__);
11075 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011076 }
11077
Jeff Johnson295189b2012-06-20 16:38:30 -070011078
Kiet Lam3b17fc82013-09-27 05:24:08 +053011079 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11080 sinfo->filled |= STATION_INFO_SIGNAL;
11081
c_hpothu09f19542014-05-30 21:53:31 +053011082 wlan_hdd_get_station_stats(pAdapter);
11083 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11084
11085 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011086 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11087 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11088 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11089 {
11090 rate_flags = pAdapter->maxRateFlags;
11091 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011092
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 //convert to the UI units of 100kbps
11094 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11095
11096#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011097 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 -070011098 sinfo->signal,
11099 pCfg->reportMaxLinkSpeed,
11100 myRate,
11101 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011102 (int) pCfg->linkSpeedRssiMid,
11103 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011104 (int) rate_flags,
11105 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011106#endif //LINKSPEED_DEBUG_ENABLED
11107
11108 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11109 {
11110 // we do not want to necessarily report the current speed
11111 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11112 {
11113 // report the max possible speed
11114 rssidx = 0;
11115 }
11116 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11117 {
11118 // report the max possible speed with RSSI scaling
11119 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11120 {
11121 // report the max possible speed
11122 rssidx = 0;
11123 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011124 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 {
11126 // report middle speed
11127 rssidx = 1;
11128 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011129 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11130 {
11131 // report middle speed
11132 rssidx = 2;
11133 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 else
11135 {
11136 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011137 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011138 }
11139 }
11140 else
11141 {
11142 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11143 hddLog(VOS_TRACE_LEVEL_ERROR,
11144 "%s: Invalid value for reportMaxLinkSpeed: %u",
11145 __func__, pCfg->reportMaxLinkSpeed);
11146 rssidx = 0;
11147 }
11148
11149 maxRate = 0;
11150
11151 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011152 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11153 OperationalRates, &ORLeng))
11154 {
11155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11156 /*To keep GUI happy*/
11157 return 0;
11158 }
11159
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 for (i = 0; i < ORLeng; i++)
11161 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011162 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 {
11164 /* Validate Rate Set */
11165 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11166 {
11167 currentRate = supported_data_rate[j].supported_rate[rssidx];
11168 break;
11169 }
11170 }
11171 /* Update MAX rate */
11172 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11173 }
11174
11175 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011176 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11177 ExtendedRates, &ERLeng))
11178 {
11179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11180 /*To keep GUI happy*/
11181 return 0;
11182 }
11183
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 for (i = 0; i < ERLeng; i++)
11185 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011186 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 {
11188 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11189 {
11190 currentRate = supported_data_rate[j].supported_rate[rssidx];
11191 break;
11192 }
11193 }
11194 /* Update MAX rate */
11195 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11196 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011197 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011198 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011199 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011200 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011201 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011203 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11204 MCSRates, &MCSLeng))
11205 {
11206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11207 /*To keep GUI happy*/
11208 return 0;
11209 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011210 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011211#ifdef WLAN_FEATURE_11AC
11212 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011213 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011215 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011216 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011217 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011219 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011221 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011223 maxMCSIdx = 7;
11224 }
11225 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11226 {
11227 maxMCSIdx = 8;
11228 }
11229 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11230 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011231 //VHT20 is supporting 0~8
11232 if (rate_flags & eHAL_TX_RATE_VHT20)
11233 maxMCSIdx = 8;
11234 else
11235 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011236 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011237
11238 if (rate_flags & eHAL_TX_RATE_VHT80)
11239 {
11240 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11241 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11242 }
11243 else if (rate_flags & eHAL_TX_RATE_VHT40)
11244 {
11245 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11246 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11247 }
11248 else if (rate_flags & eHAL_TX_RATE_VHT20)
11249 {
11250 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11251 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11252 }
11253
Leo Chang6f8870f2013-03-26 18:11:36 -070011254 maxSpeedMCS = 1;
11255 if (currentRate > maxRate)
11256 {
11257 maxRate = currentRate;
11258 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011259
Leo Chang6f8870f2013-03-26 18:11:36 -070011260 }
11261 else
11262#endif /* WLAN_FEATURE_11AC */
11263 {
11264 if (rate_flags & eHAL_TX_RATE_HT40)
11265 {
11266 rateFlag |= 1;
11267 }
11268 if (rate_flags & eHAL_TX_RATE_SGI)
11269 {
11270 rateFlag |= 2;
11271 }
11272
11273 for (i = 0; i < MCSLeng; i++)
11274 {
11275 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11276 for (j = 0; j < temp; j++)
11277 {
11278 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11279 {
11280 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11281 break;
11282 }
11283 }
11284 if ((j < temp) && (currentRate > maxRate))
11285 {
11286 maxRate = currentRate;
11287 maxSpeedMCS = 1;
11288 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11289 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 }
11291 }
11292 }
11293
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011294 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11295 {
11296 maxRate = myRate;
11297 maxSpeedMCS = 1;
11298 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11299 }
11300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011302 if (((maxRate < myRate) && (0 == rssidx)) ||
11303 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011304 {
11305 maxRate = myRate;
11306 if (rate_flags & eHAL_TX_RATE_LEGACY)
11307 {
11308 maxSpeedMCS = 0;
11309 }
11310 else
11311 {
11312 maxSpeedMCS = 1;
11313 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11314 }
11315 }
11316
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011317 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 {
11319 sinfo->txrate.legacy = maxRate;
11320#ifdef LINKSPEED_DEBUG_ENABLED
11321 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11322#endif //LINKSPEED_DEBUG_ENABLED
11323 }
11324 else
11325 {
11326 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011327#ifdef WLAN_FEATURE_11AC
11328 sinfo->txrate.nss = 1;
11329 if (rate_flags & eHAL_TX_RATE_VHT80)
11330 {
11331 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011332 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011333 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011334 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011335 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011336 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11337 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11338 }
11339 else if (rate_flags & eHAL_TX_RATE_VHT20)
11340 {
11341 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11342 }
11343#endif /* WLAN_FEATURE_11AC */
11344 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11345 {
11346 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11347 if (rate_flags & eHAL_TX_RATE_HT40)
11348 {
11349 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11350 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 if (rate_flags & eHAL_TX_RATE_SGI)
11353 {
11354 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11355 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011356
Jeff Johnson295189b2012-06-20 16:38:30 -070011357#ifdef LINKSPEED_DEBUG_ENABLED
11358 pr_info("Reporting MCS rate %d flags %x\n",
11359 sinfo->txrate.mcs,
11360 sinfo->txrate.flags );
11361#endif //LINKSPEED_DEBUG_ENABLED
11362 }
11363 }
11364 else
11365 {
11366 // report current rate instead of max rate
11367
11368 if (rate_flags & eHAL_TX_RATE_LEGACY)
11369 {
11370 //provide to the UI in units of 100kbps
11371 sinfo->txrate.legacy = myRate;
11372#ifdef LINKSPEED_DEBUG_ENABLED
11373 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11374#endif //LINKSPEED_DEBUG_ENABLED
11375 }
11376 else
11377 {
11378 //must be MCS
11379 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011380#ifdef WLAN_FEATURE_11AC
11381 sinfo->txrate.nss = 1;
11382 if (rate_flags & eHAL_TX_RATE_VHT80)
11383 {
11384 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11385 }
11386 else
11387#endif /* WLAN_FEATURE_11AC */
11388 {
11389 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11390 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 if (rate_flags & eHAL_TX_RATE_SGI)
11392 {
11393 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11394 }
11395 if (rate_flags & eHAL_TX_RATE_HT40)
11396 {
11397 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11398 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011399#ifdef WLAN_FEATURE_11AC
11400 else if (rate_flags & eHAL_TX_RATE_VHT80)
11401 {
11402 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11403 }
11404#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011405#ifdef LINKSPEED_DEBUG_ENABLED
11406 pr_info("Reporting actual MCS rate %d flags %x\n",
11407 sinfo->txrate.mcs,
11408 sinfo->txrate.flags );
11409#endif //LINKSPEED_DEBUG_ENABLED
11410 }
11411 }
11412 sinfo->filled |= STATION_INFO_TX_BITRATE;
11413
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011414 sinfo->tx_packets =
11415 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11416 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11417 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11418 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11419
11420 sinfo->tx_retries =
11421 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11422 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11423 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11424 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11425
11426 sinfo->tx_failed =
11427 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11428 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11429 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11430 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11431
11432 sinfo->filled |=
11433 STATION_INFO_TX_PACKETS |
11434 STATION_INFO_TX_RETRIES |
11435 STATION_INFO_TX_FAILED;
11436
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011437 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11438 TRACE_CODE_HDD_CFG80211_GET_STA,
11439 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011440 EXIT();
11441 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011442}
11443
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011444static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11445 u8* mac, struct station_info *sinfo)
11446{
11447 int ret;
11448
11449 vos_ssr_protect(__func__);
11450 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11451 vos_ssr_unprotect(__func__);
11452
11453 return ret;
11454}
11455
11456static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011457 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011458{
11459 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011460 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011462 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011463
Jeff Johnsone7245742012-09-05 17:12:55 -070011464 ENTER();
11465
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 if (NULL == pAdapter)
11467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 return -ENODEV;
11470 }
11471
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011472 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11473 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11474 pAdapter->sessionId, timeout));
11475
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011477 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011478
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011479 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11482 "%s: HDD context is not valid", __func__);
11483 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 }
11485
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011486 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11487 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11488 (pHddCtx->cfg_ini->fhostArpOffload) &&
11489 (eConnectionState_Associated ==
11490 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11491 {
Amar Singhald53568e2013-09-26 11:03:45 -070011492
11493 hddLog(VOS_TRACE_LEVEL_INFO,
11494 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011495 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011496 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11497 {
11498 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011499 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011500 __func__, vos_status);
11501 }
11502 }
11503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 /**The get power cmd from the supplicant gets updated by the nl only
11505 *on successful execution of the function call
11506 *we are oppositely mapped w.r.t mode in the driver
11507 **/
11508 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11509
Kiet Lam94fd2922014-06-18 19:12:43 -070011510 if (!mode)
11511 {
11512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11513 "%s: DHCP start indicated through power save", __func__);
11514
11515 pHddCtx->btCoexModeSet = TRUE;
11516 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11517 pAdapter->sessionId);
11518 }
11519 else
11520 {
11521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11522 "%s: DHCP stop indicated through power save", __func__);
11523
11524 pHddCtx->btCoexModeSet = FALSE;
11525 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11526 pAdapter->sessionId);
11527 }
11528
Jeff Johnsone7245742012-09-05 17:12:55 -070011529 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 if (VOS_STATUS_E_FAILURE == vos_status)
11531 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11533 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 return -EINVAL;
11535 }
11536 return 0;
11537}
11538
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011539static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11540 struct net_device *dev, bool mode, int timeout)
11541{
11542 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011543
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011544 vos_ssr_protect(__func__);
11545 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11546 vos_ssr_unprotect(__func__);
11547
11548 return ret;
11549}
Jeff Johnson295189b2012-06-20 16:38:30 -070011550#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11551static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11552 struct net_device *netdev,
11553 u8 key_index)
11554{
Jeff Johnsone7245742012-09-05 17:12:55 -070011555 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 return 0;
11557}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011558#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011559
11560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11561static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11562 struct net_device *dev,
11563 struct ieee80211_txq_params *params)
11564{
Jeff Johnsone7245742012-09-05 17:12:55 -070011565 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 return 0;
11567}
11568#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11569static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11570 struct ieee80211_txq_params *params)
11571{
Jeff Johnsone7245742012-09-05 17:12:55 -070011572 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 return 0;
11574}
11575#endif //LINUX_VERSION_CODE
11576
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011577static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 struct net_device *dev, u8 *mac)
11579{
11580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011581 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011582 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011583 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011584 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011585
Jeff Johnsone7245742012-09-05 17:12:55 -070011586 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011587
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011588 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 return -EINVAL;
11592 }
11593
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011594 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11595 TRACE_CODE_HDD_CFG80211_DEL_STA,
11596 pAdapter->sessionId, pAdapter->device_mode));
11597
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011598 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11599 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011601 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11604 "%s: HDD context is not valid", __func__);
11605 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011606 }
11607
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011610 )
11611 {
11612 if( NULL == mac )
11613 {
11614 v_U16_t i;
11615 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11616 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011617 if ((pAdapter->aStaInfo[i].isUsed) &&
11618 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 {
11620 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11621 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011622 "%s: Delete STA with MAC::"
11623 MAC_ADDRESS_STR,
11624 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011625 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11626 if (VOS_IS_STATUS_SUCCESS(vos_status))
11627 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 }
11629 }
11630 }
11631 else
11632 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011633
11634 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11635 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11636 {
11637 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011638 "%s: Skip this DEL STA as this is not used::"
11639 MAC_ADDRESS_STR,
11640 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011641 return -ENOENT;
11642 }
11643
11644 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11645 {
11646 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011647 "%s: Skip this DEL STA as deauth is in progress::"
11648 MAC_ADDRESS_STR,
11649 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011650 return -ENOENT;
11651 }
11652
11653 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11654
Jeff Johnson295189b2012-06-20 16:38:30 -070011655 hddLog(VOS_TRACE_LEVEL_INFO,
11656 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011657 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011659 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011660
11661 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11662 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11663 {
11664 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11665 hddLog(VOS_TRACE_LEVEL_INFO,
11666 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011667 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011668 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011669 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011670 return -ENOENT;
11671 }
11672
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 }
11674 }
11675
11676 EXIT();
11677
11678 return 0;
11679}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011680static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11681 struct net_device *dev, u8 *mac)
11682{
11683 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011684
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011685 vos_ssr_protect(__func__);
11686 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11687 vos_ssr_unprotect(__func__);
11688
11689 return ret;
11690}
11691
11692static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011693 struct net_device *dev, u8 *mac, struct station_parameters *params)
11694{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011696 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011697#ifdef FEATURE_WLAN_TDLS
11698 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011699 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011700
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011701 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11702 TRACE_CODE_HDD_CFG80211_ADD_STA,
11703 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011704 mask = params->sta_flags_mask;
11705
11706 set = params->sta_flags_set;
11707
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011708#ifdef WLAN_FEATURE_TDLS_DEBUG
11709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11710 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11711 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11712#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011713
11714 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11715 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011716 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011717 }
11718 }
11719#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011720 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011721}
11722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011723static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11724 struct net_device *dev, u8 *mac, struct station_parameters *params)
11725{
11726 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011727
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011728 vos_ssr_protect(__func__);
11729 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11730 vos_ssr_unprotect(__func__);
11731
11732 return ret;
11733}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011734#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011735
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011736static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011737 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011741 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011742 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011743 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011744 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011745 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011746 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011747 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11748 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011749
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011751 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011754 return -EINVAL;
11755 }
11756
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011757 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11758 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011759
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011760 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011761 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11763 "%s: HDD context is not valid", __func__);
11764 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011765 }
11766
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011768 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011769 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011770
Agarwal Ashish3da95242014-05-21 14:57:17 +053011771 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011772 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011773 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011774 pmksa->bssid, WNI_CFG_BSSID_LEN))
11775 {
11776 /* BSSID matched previous entry. Overwrite it. */
11777 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011778 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011779 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011780 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011782 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011784 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011785 dump_bssid(pmksa->bssid);
11786 dump_pmkid(halHandle, pmksa->pmkid);
11787 break;
11788 }
11789 }
11790
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011791 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011792 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011793
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011794 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011795 {
11796 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011797 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011798 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011799 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011800 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011801 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011802 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11803 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011804 dump_bssid(pmksa->bssid);
11805 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011807 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011808 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11809 pHddStaCtx->PMKIDCacheIndex++;
11810 else
11811 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011812 }
11813
11814
11815 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011816 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11817 __func__, pHddStaCtx->PMKIDCacheIndex );
11818
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011819 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011820 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011821 pHddStaCtx->PMKIDCache,
11822 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011823 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11824 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11825 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011826 return 0;
11827}
11828
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011829static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11830 struct cfg80211_pmksa *pmksa)
11831{
11832 int ret;
11833
11834 vos_ssr_protect(__func__);
11835 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11836 vos_ssr_unprotect(__func__);
11837
11838 return ret;
11839}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011840
Wilson Yang6507c4e2013-10-01 20:11:19 -070011841
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011842static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011843 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011844{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011845 tANI_U32 j=0;
11846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011847 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011848 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011849 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011850 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011851 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011852
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011853 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11854 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011855
11856 /* Validate pAdapter */
11857 if (NULL == pAdapter)
11858 {
11859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11860 return -EINVAL;
11861 }
11862
11863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11864 status = wlan_hdd_validate_context(pHddCtx);
11865
11866 if (0 != status)
11867 {
11868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11869 "%s: HDD context is not valid", __func__);
11870 return status;
11871 }
11872
11873 /*Retrieve halHandle*/
11874 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011875 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011876
11877 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011878 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011879 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011880 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11881 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011882 }
11883
11884 /*find the matching PMKSA entry from j=0 to (index-1),
11885 * and delete the matched one
11886 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011887 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011888 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011889 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011890 pmksa->bssid,
11891 WNI_CFG_BSSID_LEN))
11892 {
11893 /* BSSID matched entry */
11894 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011895 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011896 {
11897 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011898 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11899 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11900 VOS_MAC_ADDR_SIZE);
11901 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11902 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11903 CSR_RSN_PMKID_SIZE);
11904 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011905
11906 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011907 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11908 VOS_MAC_ADDR_SIZE);
11909 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11910 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011911 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011912 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011913 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011914 if (eHAL_STATUS_SUCCESS !=
11915 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011916 {
11917 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011918 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011919 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011920 }
11921
11922 dump_bssid(pmksa->bssid);
11923 dump_pmkid(halHandle,pmksa->pmkid);
11924
11925 break;
11926 }
11927 }
11928
11929 /* we compare all entries,but cannot find matching entry */
11930 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
11931 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011932 hddLog(VOS_TRACE_LEVEL_FATAL,
11933 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
11934 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011935 dump_bssid(pmksa->bssid);
11936 dump_pmkid(halHandle, pmksa->pmkid);
11937 return -EINVAL;
11938 }
Wilson Yangef657d32014-01-15 19:19:23 -080011939 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011940}
11941
Wilson Yang6507c4e2013-10-01 20:11:19 -070011942
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011943static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
11944 struct cfg80211_pmksa *pmksa)
11945{
11946 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011947
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011948 vos_ssr_protect(__func__);
11949 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
11950 vos_ssr_unprotect(__func__);
11951
11952 return ret;
11953
11954}
11955
11956static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011957{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011958 tANI_U32 j=0;
11959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011960 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011961 tHalHandle halHandle;
11962 hdd_context_t *pHddCtx;
11963 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080011964 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011965
11966 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
11967
11968 /* Validate pAdapter */
11969 if (NULL == pAdapter)
11970 {
11971 hddLog(VOS_TRACE_LEVEL_ERROR,
11972 "%s: Invalid Adapter" ,__func__);
11973 return -EINVAL;
11974 }
11975
11976 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11977 status = wlan_hdd_validate_context(pHddCtx);
11978
11979 if (0 != status)
11980 {
11981 hddLog(VOS_TRACE_LEVEL_ERROR,
11982 "%s: HDD context is not valid", __func__);
11983 return status;
11984 }
11985
11986 /*Retrieve halHandle*/
11987 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011988 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011989
11990 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011991 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011992 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053011993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053011994 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011995 }
11996
11997 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011998 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011999 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012000 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012001 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012002 if (eHAL_STATUS_SUCCESS !=
12003 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012004 {
12005 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12006 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012007 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012008 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012009 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012010 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12011 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12012 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012013
Agarwal Ashish3da95242014-05-21 14:57:17 +053012014 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012015 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012016}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012017
12018static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12019{
12020 int ret;
12021
12022 vos_ssr_protect(__func__);
12023 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12024 vos_ssr_unprotect(__func__);
12025
12026 return ret;
12027}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012028#endif
12029
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012030#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012031static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12032 struct net_device *dev,
12033 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012034{
12035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12036 hdd_station_ctx_t *pHddStaCtx;
12037
12038 if (NULL == pAdapter)
12039 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012041 return -ENODEV;
12042 }
12043
12044 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12045
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12047 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12048 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012049 // Added for debug on reception of Re-assoc Req.
12050 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12051 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012052 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012053 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012054 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012055 }
12056
12057#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012058 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012059 ftie->ie_len);
12060#endif
12061
12062 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012063 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12064 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012065 ftie->ie_len);
12066 return 0;
12067}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012068
12069static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12070 struct net_device *dev,
12071 struct cfg80211_update_ft_ies_params *ftie)
12072{
12073 int ret;
12074
12075 vos_ssr_protect(__func__);
12076 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12077 vos_ssr_unprotect(__func__);
12078
12079 return ret;
12080}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012081#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012082
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012083#ifdef FEATURE_WLAN_SCAN_PNO
12084
12085void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12086 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12087{
12088 int ret;
12089 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12090 hdd_context_t *pHddCtx;
12091
Nirav Shah80830bf2013-12-31 16:35:12 +053012092 ENTER();
12093
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012094 if (NULL == pAdapter)
12095 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012097 "%s: HDD adapter is Null", __func__);
12098 return ;
12099 }
12100
12101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12102 if (NULL == pHddCtx)
12103 {
12104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12105 "%s: HDD context is Null!!!", __func__);
12106 return ;
12107 }
12108
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012109 spin_lock(&pHddCtx->schedScan_lock);
12110 if (TRUE == pHddCtx->isWiphySuspended)
12111 {
12112 pHddCtx->isSchedScanUpdatePending = TRUE;
12113 spin_unlock(&pHddCtx->schedScan_lock);
12114 hddLog(VOS_TRACE_LEVEL_INFO,
12115 "%s: Update cfg80211 scan database after it resume", __func__);
12116 return ;
12117 }
12118 spin_unlock(&pHddCtx->schedScan_lock);
12119
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012120 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12121
12122 if (0 > ret)
12123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12124
12125 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12127 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012128}
12129
12130/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012131 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012132 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012133 */
12134static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12135{
12136 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12137 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012138 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012139 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12140 int status = 0;
12141 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12142
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012143 /* The current firmware design does not allow PNO during any
12144 * active sessions. Hence, determine the active sessions
12145 * and return a failure.
12146 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012147 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12148 {
12149 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012150 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012151
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012152 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12153 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12154 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12155 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12156 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12157 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012158 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012159 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012160 }
12161 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12162 pAdapterNode = pNext;
12163 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012164 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012165}
12166
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012167void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12168{
12169 hdd_adapter_t *pAdapter = callbackContext;
12170 hdd_context_t *pHddCtx;
12171
12172 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12173 {
12174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12175 FL("Invalid adapter or adapter has invalid magic"));
12176 return;
12177 }
12178
12179 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12180 if (0 != wlan_hdd_validate_context(pHddCtx))
12181 {
12182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12183 FL("HDD context is not valid"));
12184 return;
12185 }
12186
12187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12188 FL("PNO enable response status = %d"), status);
12189
12190 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12191 complete(&pAdapter->pno_comp_var);
12192}
12193
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012194/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012195 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12196 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012197 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012198static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012199 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12200{
12201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12202 tpSirPNOScanReq pPnoRequest = NULL;
12203 hdd_context_t *pHddCtx;
12204 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012205 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012206 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12207 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012208 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12209 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012210 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012211
12212 if (NULL == pAdapter)
12213 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012215 "%s: HDD adapter is Null", __func__);
12216 return -ENODEV;
12217 }
12218
12219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012220 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012221
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012222 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012223 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12225 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012226 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012227 }
12228
12229 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12230 if (NULL == hHal)
12231 {
12232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12233 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012234 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012235 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012236
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012237 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012238 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012239 {
12240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12241 "%s: aborting the existing scan is unsuccessfull", __func__);
12242 return -EBUSY;
12243 }
12244
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012245 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012246 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012248 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012249 return -EBUSY;
12250 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012251
c_hpothu37f21312014-04-09 21:49:54 +053012252 if (TRUE == pHddCtx->isPnoEnable)
12253 {
12254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12255 FL("already PNO is enabled"));
12256 return -EBUSY;
12257 }
12258 pHddCtx->isPnoEnable = TRUE;
12259
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012260 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12261 if (NULL == pPnoRequest)
12262 {
12263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12264 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012265 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012266 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012267 }
12268
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012269 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012270 pPnoRequest->enable = 1; /*Enable PNO */
12271 pPnoRequest->ucNetworksCount = request->n_match_sets;
12272
12273 if (( !pPnoRequest->ucNetworksCount ) ||
12274 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12275 {
12276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012277 "%s: Network input is not correct %d Max Network supported is %d",
12278 __func__, pPnoRequest->ucNetworksCount,
12279 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012280 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012281 goto error;
12282 }
12283
12284 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12285 {
12286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012287 "%s: Incorrect number of channels %d",
12288 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012289 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012290 goto error;
12291 }
12292
12293 /* Framework provides one set of channels(all)
12294 * common for all saved profile */
12295 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12296 channels_allowed, &num_channels_allowed))
12297 {
12298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12299 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012300 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012301 goto error;
12302 }
12303 /* Checking each channel against allowed channel list */
12304 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012305 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012306 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012307 char chList [(request->n_channels*5)+1];
12308 int len;
12309 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012310 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012311 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012312 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012313 if (request->channels[i]->hw_value == channels_allowed[indx])
12314 {
12315 valid_ch[num_ch++] = request->channels[i]->hw_value;
12316 len += snprintf(chList+len, 5, "%d ",
12317 request->channels[i]->hw_value);
12318 break ;
12319 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012320 }
12321 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012322 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12323 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012324
12325 /* Filling per profile params */
12326 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12327 {
12328 pPnoRequest->aNetworks[i].ssId.length =
12329 request->match_sets[i].ssid.ssid_len;
12330
12331 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12332 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12333 {
12334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012335 "%s: SSID Len %d is not correct for network %d",
12336 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012337 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012338 goto error;
12339 }
12340
12341 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12342 request->match_sets[i].ssid.ssid,
12343 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12345 "%s: SSID of network %d is %s ", __func__,
12346 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012347 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12348 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12349 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12350
12351 /*Copying list of valid channel into request */
12352 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12353 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12354
12355 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12356 }
12357
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012359 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012360 if ((0 < request->ie_len) && (NULL != request->ie))
12361 {
12362 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12363 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12364 pPnoRequest->us24GProbeTemplateLen);
12365
12366 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12367 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12368 pPnoRequest->us5GProbeTemplateLen);
12369 }
12370
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012371 /* Driver gets only one time interval which is hardcoded in
12372 * supplicant for 10000ms. Taking power consumption into account 6 timers
12373 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12374 * 80,160,320 secs. And number of scan cycle for each timer
12375 * is configurable through INI param gPNOScanTimerRepeatValue.
12376 * If it is set to 0 only one timer will be used and PNO scan cycle
12377 * will be repeated after each interval specified by supplicant
12378 * till PNO is disabled.
12379 */
12380 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12381 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12382 else
12383 pPnoRequest->scanTimers.ucScanTimersCount =
12384 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12385
12386 tempInterval = (request->interval)/1000;
12387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12388 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12389 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12390 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12391 {
12392 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12393 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12394 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12395 tempInterval *= 2;
12396 }
12397 //Repeat last timer until pno disabled.
12398 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12399
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012400 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012401
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012402 INIT_COMPLETION(pAdapter->pno_comp_var);
12403 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12404 pPnoRequest->callbackContext = pAdapter;
12405 pAdapter->pno_req_status = 0;
12406
Nirav Shah80830bf2013-12-31 16:35:12 +053012407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12408 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12409 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12410 pPnoRequest->scanTimers.ucScanTimersCount);
12411
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012412 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12413 pPnoRequest, pAdapter->sessionId,
12414 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12415 if (eHAL_STATUS_SUCCESS != status)
12416 {
12417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012418 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012419 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012420 goto error;
12421 }
12422
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012423 ret = wait_for_completion_timeout(
12424 &pAdapter->pno_comp_var,
12425 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12426 if (0 >= ret)
12427 {
12428 // Did not receive the response for PNO enable in time.
12429 // Assuming the PNO enable was success.
12430 // Returning error from here, because we timeout, results
12431 // in side effect of Wifi (Wifi Setting) not to work.
12432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12433 FL("Timed out waiting for PNO to be Enabled"));
12434 ret = 0;
12435 goto error;
12436 }
12437
12438 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012439 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012440
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012441error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12443 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012444 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012445 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012446 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012447}
12448
12449/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012450 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12451 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012452 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012453static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12454 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12455{
12456 int ret;
12457
12458 vos_ssr_protect(__func__);
12459 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12460 vos_ssr_unprotect(__func__);
12461
12462 return ret;
12463}
12464
12465/*
12466 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12467 * Function to disable PNO
12468 */
12469static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012470 struct net_device *dev)
12471{
12472 eHalStatus status = eHAL_STATUS_FAILURE;
12473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12474 hdd_context_t *pHddCtx;
12475 tHalHandle hHal;
12476 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012477 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012478
12479 ENTER();
12480
12481 if (NULL == pAdapter)
12482 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012484 "%s: HDD adapter is Null", __func__);
12485 return -ENODEV;
12486 }
12487
12488 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012489
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012490 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012491 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012493 "%s: HDD context is Null", __func__);
12494 return -ENODEV;
12495 }
12496
12497 /* The return 0 is intentional when isLogpInProgress and
12498 * isLoadUnloadInProgress. We did observe a crash due to a return of
12499 * failure in sched_scan_stop , especially for a case where the unload
12500 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12501 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12502 * success. If it returns a failure , then its next invocation due to the
12503 * clean up of the second interface will have the dev pointer corresponding
12504 * to the first one leading to a crash.
12505 */
12506 if (pHddCtx->isLogpInProgress)
12507 {
12508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12509 "%s: LOGP in Progress. Ignore!!!", __func__);
12510 return ret;
12511 }
12512
Mihir Shete18156292014-03-11 15:38:30 +053012513 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012514 {
12515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12516 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12517 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012518 }
12519
12520 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12521 if (NULL == hHal)
12522 {
12523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12524 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012525 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012526 }
12527
12528 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12529 if (NULL == pPnoRequest)
12530 {
12531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12532 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012533 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012534 }
12535
12536 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12537 pPnoRequest->enable = 0; /* Disable PNO */
12538 pPnoRequest->ucNetworksCount = 0;
12539
12540 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12541 pAdapter->sessionId,
12542 NULL, pAdapter);
12543 if (eHAL_STATUS_SUCCESS != status)
12544 {
12545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12546 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012547 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012548 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012549 }
c_hpothu37f21312014-04-09 21:49:54 +053012550 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012551
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012552error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012554 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012555 vos_mem_free(pPnoRequest);
12556
12557 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012558 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012559}
12560
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012561/*
12562 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12563 * NL interface to disable PNO
12564 */
12565static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12566 struct net_device *dev)
12567{
12568 int ret;
12569
12570 vos_ssr_protect(__func__);
12571 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12572 vos_ssr_unprotect(__func__);
12573
12574 return ret;
12575}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012576#endif /*FEATURE_WLAN_SCAN_PNO*/
12577
12578
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012579#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012580#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012581static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12582 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012583 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12584#else
12585static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12586 u8 *peer, u8 action_code, u8 dialog_token,
12587 u16 status_code, const u8 *buf, size_t len)
12588#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012589{
12590
12591 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12592 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012593 u8 peerMac[6];
12594 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012595 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012596 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012597 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012598#if !(TDLS_MGMT_VERSION2)
12599 u32 peer_capability = 0;
12600#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012601 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012602
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12604 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12605 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012606 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012609 "Invalid arguments");
12610 return -EINVAL;
12611 }
12612
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012613 if (pHddCtx->isLogpInProgress)
12614 {
12615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12616 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012617 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012618 return -EBUSY;
12619 }
12620
Hoonki Lee27511902013-03-14 18:19:06 -070012621 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012622 {
Hoonki Lee27511902013-03-14 18:19:06 -070012623 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12624 "%s: TDLS mode is disabled OR not enabled in FW."
12625 MAC_ADDRESS_STR " action %d declined.",
12626 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012627 return -ENOTSUPP;
12628 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012629
Hoonki Lee27511902013-03-14 18:19:06 -070012630 /* other than teardown frame, other mgmt frames are not sent if disabled */
12631 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12632 {
12633 /* if tdls_mode is disabled to respond to peer's request */
12634 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12635 {
12636 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12637 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012638 " TDLS mode is disabled. action %d declined.",
12639 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012640
12641 return -ENOTSUPP;
12642 }
12643 }
12644
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012645 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12646 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012647 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012648 {
12649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012650 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012651 " TDLS setup is ongoing. action %d declined.",
12652 __func__, MAC_ADDR_ARRAY(peer), action_code);
12653 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012654 }
12655 }
12656
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012657 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12658 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012659 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012660 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12661 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012662 {
12663 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12664 we return error code at 'add_station()'. Hence we have this
12665 check again in addtion to add_station().
12666 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012667 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012668 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12670 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012671 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12672 __func__, MAC_ADDR_ARRAY(peer), action_code,
12673 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012674 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012675 }
12676 else
12677 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012678 /* maximum reached. tweak to send error code to peer and return
12679 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012680 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12682 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012683 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12684 __func__, MAC_ADDR_ARRAY(peer), status_code,
12685 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012686 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012687 /* fall through to send setup resp with failure status
12688 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012689 }
12690 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012691 else
12692 {
12693 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012694 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012695 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012696 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012698 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12699 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012700 return -EPERM;
12701 }
12702 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012703 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012704 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012705
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012706#ifdef WLAN_FEATURE_TDLS_DEBUG
12707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012708 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012709 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12710 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012711#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012712
Hoonki Leea34dd892013-02-05 22:56:02 -080012713 /*Except teardown responder will not be used so just make 0*/
12714 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012715 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012716 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012717
12718 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012719 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012720
12721 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12722 responder = pTdlsPeer->is_responder;
12723 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012724 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012726 "%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 -070012727 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12728 dialog_token, status_code, len);
12729 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012730 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012731 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012732
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012733 /* For explicit trigger of DIS_REQ come out of BMPS for
12734 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012735 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012736 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12737 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012738 {
12739 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12740 {
12741 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012742 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012743 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12744 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012745 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12746 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012747 }
12748
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012749 /* make sure doesn't call send_mgmt() while it is pending */
12750 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12751 {
12752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012753 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012754 __func__, MAC_ADDR_ARRAY(peer), action_code);
12755 return -EBUSY;
12756 }
12757
12758 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012759 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12760
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012761 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012762 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012763
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012764 if (VOS_STATUS_SUCCESS != status)
12765 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12767 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012768 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012769 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012770 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012771 }
12772
Hoonki Leed37cbb32013-04-20 00:31:14 -070012773 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12774 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12775
12776 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012777 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012779 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012780 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012781 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012782
12783 if (pHddCtx->isLogpInProgress)
12784 {
12785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12786 "%s: LOGP in Progress. Ignore!!!", __func__);
12787 return -EAGAIN;
12788 }
12789
Hoonki Leed37cbb32013-04-20 00:31:14 -070012790 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012791 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012792 }
12793
Gopichand Nakkala05922802013-03-14 12:23:19 -070012794 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012795 {
12796 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012797 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012798 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012799
Hoonki Leea34dd892013-02-05 22:56:02 -080012800 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12801 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012802 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012803 }
12804 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12805 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012806 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012807 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012808
12809 return 0;
12810}
12811
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012812static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012813 u8 *peer, enum nl80211_tdls_operation oper)
12814{
12815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12816 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012817 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012818 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12821 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12822 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012823 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012824 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012826 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012827 return -EINVAL;
12828 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012829
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012830 status = wlan_hdd_validate_context(pHddCtx);
12831
12832 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12835 "%s: HDD context is not valid", __func__);
12836 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012837 }
12838
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012839
12840 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012841 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012842 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012844 "TDLS Disabled in INI OR not enabled in FW. "
12845 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012846 return -ENOTSUPP;
12847 }
12848
12849 switch (oper) {
12850 case NL80211_TDLS_ENABLE_LINK:
12851 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012852 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012853 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012854 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012855
Sunil Dutt41de4e22013-11-14 18:09:02 +053012856 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12857
12858 if ( NULL == pTdlsPeer ) {
12859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12860 " (oper %d) not exsting. ignored",
12861 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12862 return -EINVAL;
12863 }
12864
12865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12866 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12867 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12868 "NL80211_TDLS_ENABLE_LINK");
12869
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012870 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12871 {
12872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12873 MAC_ADDRESS_STR " failed",
12874 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12875 return -EINVAL;
12876 }
12877
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012878 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012879 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012880 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012881
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012882 if (0 != wlan_hdd_tdls_get_link_establish_params(
12883 pAdapter, peer,&tdlsLinkEstablishParams)) {
12884 return -EINVAL;
12885 }
12886 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012887
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012888 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12889 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12890 /* Send TDLS peer UAPSD capabilities to the firmware and
12891 * register with the TL on after the response for this operation
12892 * is received .
12893 */
12894 ret = wait_for_completion_interruptible_timeout(
12895 &pAdapter->tdls_link_establish_req_comp,
12896 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12897 if (ret <= 0)
12898 {
12899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12900 "%s: Link Establish Request Faled Status %ld",
12901 __func__, ret);
12902 return -EINVAL;
12903 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012904 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012905 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012906 /* Mark TDLS client Authenticated .*/
12907 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12908 pTdlsPeer->staId,
12909 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012910 if (VOS_STATUS_SUCCESS == status)
12911 {
Hoonki Lee14621352013-04-16 17:51:19 -070012912 if (pTdlsPeer->is_responder == 0)
12913 {
12914 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12915
12916 wlan_hdd_tdls_timer_restart(pAdapter,
12917 &pTdlsPeer->initiatorWaitTimeoutTimer,
12918 WAIT_TIME_TDLS_INITIATOR);
12919 /* suspend initiator TX until it receives direct packet from the
12920 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12921 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12922 &staId, NULL);
12923 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012924 wlan_hdd_tdls_increment_peer_count(pAdapter);
12925 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012926 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012927
12928 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012929 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
12930 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012931 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012932 int ac;
12933 uint8 ucAc[4] = { WLANTL_AC_VO,
12934 WLANTL_AC_VI,
12935 WLANTL_AC_BK,
12936 WLANTL_AC_BE };
12937 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
12938 for(ac=0; ac < 4; ac++)
12939 {
12940 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12941 pTdlsPeer->staId, ucAc[ac],
12942 tlTid[ac], tlTid[ac], 0, 0,
12943 WLANTL_BI_DIR );
12944 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012945 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012946 }
12947
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012948 }
12949 break;
12950 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080012951 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053012952 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12953
12954 if ( NULL == pTdlsPeer ) {
12955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12956 " (oper %d) not exsting. ignored",
12957 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12958 return -EINVAL;
12959 }
12960
12961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12962 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12963 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12964 "NL80211_TDLS_DISABLE_LINK");
12965
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012966 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080012967 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012968 long status;
12969
12970 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
12971
Lee Hoonkic1262f22013-01-24 21:59:00 -080012972 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
12973 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012974
12975 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
12976 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
12977 if (status <= 0)
12978 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012979 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12981 "%s: Del station failed status %ld",
12982 __func__, status);
12983 return -EPERM;
12984 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012985 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012986 }
12987 else
12988 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12990 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012991 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012992 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012993 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012994 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053012995 {
12996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12997 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
12998 __func__, MAC_ADDR_ARRAY(peer));
12999
13000 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13001 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13002
13003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13004 " %s TDLS External control and Implicit Trigger not enabled ",
13005 __func__);
13006 return -ENOTSUPP;
13007 }
13008
Sunil Dutt41de4e22013-11-14 18:09:02 +053013009
13010 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13011
13012 if ( NULL == pTdlsPeer ) {
13013 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13014 " peer not exsting",
13015 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013016 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013017 }
13018 else {
13019 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13020 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13021 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013022
13023 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13024 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013025 break;
13026 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013027 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013028 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013029 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13031 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13032 __func__, MAC_ADDR_ARRAY(peer));
13033
13034 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13035 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13036
13037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13038 " %s TDLS External control and Implicit Trigger not enabled ",
13039 __func__);
13040 return -ENOTSUPP;
13041 }
13042
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013043 /* To cater the requirement of establishing the TDLS link
13044 * irrespective of the data traffic , get an entry of TDLS peer.
13045 */
13046 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13047 if (pTdlsPeer == NULL) {
13048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13049 "%s: peer " MAC_ADDRESS_STR " not existing",
13050 __func__, MAC_ADDR_ARRAY(peer));
13051 return -EINVAL;
13052 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013053
13054 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13055
13056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13057 " %s TDLS Add Force Peer Failed",
13058 __func__);
13059 return -EINVAL;
13060 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013061 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013062 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013063 case NL80211_TDLS_DISCOVERY_REQ:
13064 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13066 "%s: We don't support in-driver setup/teardown/discovery "
13067 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013068 return -ENOTSUPP;
13069 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13071 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013072 return -ENOTSUPP;
13073 }
13074 return 0;
13075}
Chilam NG571c65a2013-01-19 12:27:36 +053013076
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013077static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13078 u8 *peer, enum nl80211_tdls_operation oper)
13079{
13080 int ret;
13081
13082 vos_ssr_protect(__func__);
13083 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13084 vos_ssr_unprotect(__func__);
13085
13086 return ret;
13087}
13088
Chilam NG571c65a2013-01-19 12:27:36 +053013089int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13090 struct net_device *dev, u8 *peer)
13091{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013092 hddLog(VOS_TRACE_LEVEL_INFO,
13093 "tdls send discover req: "MAC_ADDRESS_STR,
13094 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013095
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013096#if TDLS_MGMT_VERSION2
13097 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13098 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13099#else
Chilam NG571c65a2013-01-19 12:27:36 +053013100 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13101 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013102#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013103}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013104#endif
13105
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013106#ifdef WLAN_FEATURE_GTK_OFFLOAD
13107/*
13108 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13109 * Callback rountine called upon receiving response for
13110 * get offload info
13111 */
13112void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13113 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13114{
13115
13116 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013117 tANI_U8 tempReplayCounter[8];
13118 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013119
13120 ENTER();
13121
13122 if (NULL == pAdapter)
13123 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013125 "%s: HDD adapter is Null", __func__);
13126 return ;
13127 }
13128
13129 if (NULL == pGtkOffloadGetInfoRsp)
13130 {
13131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13132 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13133 return ;
13134 }
13135
13136 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13137 {
13138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13139 "%s: wlan Failed to get replay counter value",
13140 __func__);
13141 return ;
13142 }
13143
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13145 /* Update replay counter */
13146 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13147 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13148
13149 {
13150 /* changing from little to big endian since supplicant
13151 * works on big endian format
13152 */
13153 int i;
13154 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13155
13156 for (i = 0; i < 8; i++)
13157 {
13158 tempReplayCounter[7-i] = (tANI_U8)p[i];
13159 }
13160 }
13161
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013162 /* Update replay counter to NL */
13163 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013164 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013165}
13166
13167/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013168 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013169 * This function is used to offload GTK rekeying job to the firmware.
13170 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013171int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013172 struct cfg80211_gtk_rekey_data *data)
13173{
13174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13175 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13176 hdd_station_ctx_t *pHddStaCtx;
13177 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013178 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013179 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013180 eHalStatus status = eHAL_STATUS_FAILURE;
13181
13182 ENTER();
13183
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013184
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013185 if (NULL == pAdapter)
13186 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013188 "%s: HDD adapter is Null", __func__);
13189 return -ENODEV;
13190 }
13191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13193 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13194 pAdapter->sessionId, pAdapter->device_mode));
13195
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013196 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013197
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013198 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013199 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13201 "%s: HDD context is not valid", __func__);
13202 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013203 }
13204
13205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13206 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13207 if (NULL == hHal)
13208 {
13209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13210 "%s: HAL context is Null!!!", __func__);
13211 return -EAGAIN;
13212 }
13213
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013214 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13215 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13216 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13217 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013218 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013219 {
13220 /* changing from big to little endian since driver
13221 * works on little endian format
13222 */
13223 tANI_U8 *p =
13224 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13225 int i;
13226
13227 for (i = 0; i < 8; i++)
13228 {
13229 p[7-i] = data->replay_ctr[i];
13230 }
13231 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013232
13233 if (TRUE == pHddCtx->hdd_wlan_suspended)
13234 {
13235 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013236 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13237 sizeof (tSirGtkOffloadParams));
13238 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013239 pAdapter->sessionId);
13240
13241 if (eHAL_STATUS_SUCCESS != status)
13242 {
13243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13244 "%s: sme_SetGTKOffload failed, returned %d",
13245 __func__, status);
13246 return status;
13247 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13249 "%s: sme_SetGTKOffload successfull", __func__);
13250 }
13251 else
13252 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13254 "%s: wlan not suspended GTKOffload request is stored",
13255 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013256 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013257
13258 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013259}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013261int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13262 struct cfg80211_gtk_rekey_data *data)
13263{
13264 int ret;
13265
13266 vos_ssr_protect(__func__);
13267 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13268 vos_ssr_unprotect(__func__);
13269
13270 return ret;
13271}
13272#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013273/*
13274 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13275 * This function is used to set access control policy
13276 */
13277static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13278 struct net_device *dev, const struct cfg80211_acl_data *params)
13279{
13280 int i;
13281 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13282 hdd_hostapd_state_t *pHostapdState;
13283 tsap_Config_t *pConfig;
13284 v_CONTEXT_t pVosContext = NULL;
13285 hdd_context_t *pHddCtx;
13286 int status;
13287
13288 ENTER();
13289
13290 if (NULL == pAdapter)
13291 {
13292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13293 "%s: HDD adapter is Null", __func__);
13294 return -ENODEV;
13295 }
13296
13297 if (NULL == params)
13298 {
13299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13300 "%s: params is Null", __func__);
13301 return -EINVAL;
13302 }
13303
13304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13305 status = wlan_hdd_validate_context(pHddCtx);
13306
13307 if (0 != status)
13308 {
13309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13310 "%s: HDD context is not valid", __func__);
13311 return status;
13312 }
13313
13314 pVosContext = pHddCtx->pvosContext;
13315 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13316
13317 if (NULL == pHostapdState)
13318 {
13319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13320 "%s: pHostapdState is Null", __func__);
13321 return -EINVAL;
13322 }
13323
13324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13325 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13326
13327 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13328 {
13329 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13330
13331 /* default value */
13332 pConfig->num_accept_mac = 0;
13333 pConfig->num_deny_mac = 0;
13334
13335 /**
13336 * access control policy
13337 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13338 * listed in hostapd.deny file.
13339 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13340 * listed in hostapd.accept file.
13341 */
13342 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13343 {
13344 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13345 }
13346 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13347 {
13348 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13349 }
13350 else
13351 {
13352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13353 "%s:Acl Policy : %d is not supported",
13354 __func__, params->acl_policy);
13355 return -ENOTSUPP;
13356 }
13357
13358 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13359 {
13360 pConfig->num_accept_mac = params->n_acl_entries;
13361 for (i = 0; i < params->n_acl_entries; i++)
13362 {
13363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13364 "** Add ACL MAC entry %i in WhiletList :"
13365 MAC_ADDRESS_STR, i,
13366 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13367
13368 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13369 sizeof(qcmacaddr));
13370 }
13371 }
13372 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13373 {
13374 pConfig->num_deny_mac = params->n_acl_entries;
13375 for (i = 0; i < params->n_acl_entries; i++)
13376 {
13377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13378 "** Add ACL MAC entry %i in BlackList :"
13379 MAC_ADDRESS_STR, i,
13380 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13381
13382 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13383 sizeof(qcmacaddr));
13384 }
13385 }
13386
13387 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13388 {
13389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13390 "%s: SAP Set Mac Acl fail", __func__);
13391 return -EINVAL;
13392 }
13393 }
13394 else
13395 {
13396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013397 "%s: Invalid device_mode = %s (%d)",
13398 __func__, hdd_device_modetoString(pAdapter->device_mode),
13399 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013400 return -EINVAL;
13401 }
13402
13403 return 0;
13404}
13405
Leo Chang9056f462013-08-01 19:21:11 -070013406#ifdef WLAN_NL80211_TESTMODE
13407#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013408void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013409(
13410 void *pAdapter,
13411 void *indCont
13412)
13413{
Leo Changd9df8aa2013-09-26 13:32:26 -070013414 tSirLPHBInd *lphbInd;
13415 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013416 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013417
13418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013419 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013420
c_hpothu73f35e62014-04-18 13:40:08 +053013421 if (pAdapter == NULL)
13422 {
13423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13424 "%s: pAdapter is NULL\n",__func__);
13425 return;
13426 }
13427
Leo Chang9056f462013-08-01 19:21:11 -070013428 if (NULL == indCont)
13429 {
13430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013431 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013432 return;
13433 }
13434
c_hpothu73f35e62014-04-18 13:40:08 +053013435 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013436 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013437 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013438 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013439 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013440 GFP_ATOMIC);
13441 if (!skb)
13442 {
13443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13444 "LPHB timeout, NL buffer alloc fail");
13445 return;
13446 }
13447
Leo Changac3ba772013-10-07 09:47:04 -070013448 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013449 {
13450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13451 "WLAN_HDD_TM_ATTR_CMD put fail");
13452 goto nla_put_failure;
13453 }
Leo Changac3ba772013-10-07 09:47:04 -070013454 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013455 {
13456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13457 "WLAN_HDD_TM_ATTR_TYPE put fail");
13458 goto nla_put_failure;
13459 }
Leo Changac3ba772013-10-07 09:47:04 -070013460 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013461 sizeof(tSirLPHBInd), lphbInd))
13462 {
13463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13464 "WLAN_HDD_TM_ATTR_DATA put fail");
13465 goto nla_put_failure;
13466 }
Leo Chang9056f462013-08-01 19:21:11 -070013467 cfg80211_testmode_event(skb, GFP_ATOMIC);
13468 return;
13469
13470nla_put_failure:
13471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13472 "NLA Put fail");
13473 kfree_skb(skb);
13474
13475 return;
13476}
13477#endif /* FEATURE_WLAN_LPHB */
13478
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013479static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013480{
13481 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13482 int err = 0;
13483#ifdef FEATURE_WLAN_LPHB
13484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013485 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013486#endif /* FEATURE_WLAN_LPHB */
13487
13488 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13489 if (err)
13490 {
13491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13492 "%s Testmode INV ATTR", __func__);
13493 return err;
13494 }
13495
13496 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13497 {
13498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13499 "%s Testmode INV CMD", __func__);
13500 return -EINVAL;
13501 }
13502
13503 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13504 {
13505#ifdef FEATURE_WLAN_LPHB
13506 /* Low Power Heartbeat configuration request */
13507 case WLAN_HDD_TM_CMD_WLAN_HB:
13508 {
13509 int buf_len;
13510 void *buf;
13511 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013512 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013513
13514 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13515 {
13516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13517 "%s Testmode INV DATA", __func__);
13518 return -EINVAL;
13519 }
13520
13521 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13522 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013523
13524 hb_params_temp =(tSirLPHBReq *)buf;
13525 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13526 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13527 return -EINVAL;
13528
Leo Chang9056f462013-08-01 19:21:11 -070013529 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13530 if (NULL == hb_params)
13531 {
13532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13533 "%s Request Buffer Alloc Fail", __func__);
13534 return -EINVAL;
13535 }
13536
13537 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013538 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13539 hb_params,
13540 wlan_hdd_cfg80211_lphb_ind_handler);
13541 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013542 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13544 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013545 vos_mem_free(hb_params);
13546 }
Leo Chang9056f462013-08-01 19:21:11 -070013547 return 0;
13548 }
13549#endif /* FEATURE_WLAN_LPHB */
13550 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13552 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013553 return -EOPNOTSUPP;
13554 }
13555
13556 return err;
13557}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013558
13559static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13560{
13561 int ret;
13562
13563 vos_ssr_protect(__func__);
13564 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13565 vos_ssr_unprotect(__func__);
13566
13567 return ret;
13568}
Leo Chang9056f462013-08-01 19:21:11 -070013569#endif /* CONFIG_NL80211_TESTMODE */
13570
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013571static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013572 struct net_device *dev,
13573 int idx, struct survey_info *survey)
13574{
13575 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13576 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013577 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013578 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013579 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013580 v_S7_t snr,rssi;
13581 int status, i, j, filled = 0;
13582
13583 ENTER();
13584
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013585 if (NULL == pAdapter)
13586 {
13587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13588 "%s: HDD adapter is Null", __func__);
13589 return -ENODEV;
13590 }
13591
13592 if (NULL == wiphy)
13593 {
13594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13595 "%s: wiphy is Null", __func__);
13596 return -ENODEV;
13597 }
13598
13599 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13600 status = wlan_hdd_validate_context(pHddCtx);
13601
13602 if (0 != status)
13603 {
13604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13605 "%s: HDD context is not valid", __func__);
13606 return status;
13607 }
13608
Mihir Sheted9072e02013-08-21 17:02:29 +053013609 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13610
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013611 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013612 0 != pAdapter->survey_idx ||
13613 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013614 {
13615 /* The survey dump ops when implemented completely is expected to
13616 * return a survey of all channels and the ops is called by the
13617 * kernel with incremental values of the argument 'idx' till it
13618 * returns -ENONET. But we can only support the survey for the
13619 * operating channel for now. survey_idx is used to track
13620 * that the ops is called only once and then return -ENONET for
13621 * the next iteration
13622 */
13623 pAdapter->survey_idx = 0;
13624 return -ENONET;
13625 }
13626
13627 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13628
13629 wlan_hdd_get_snr(pAdapter, &snr);
13630 wlan_hdd_get_rssi(pAdapter, &rssi);
13631
13632 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13633 hdd_wlan_get_freq(channel, &freq);
13634
13635
13636 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13637 {
13638 if (NULL == wiphy->bands[i])
13639 {
13640 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13641 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13642 continue;
13643 }
13644
13645 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13646 {
13647 struct ieee80211_supported_band *band = wiphy->bands[i];
13648
13649 if (band->channels[j].center_freq == (v_U16_t)freq)
13650 {
13651 survey->channel = &band->channels[j];
13652 /* The Rx BDs contain SNR values in dB for the received frames
13653 * while the supplicant expects noise. So we calculate and
13654 * return the value of noise (dBm)
13655 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13656 */
13657 survey->noise = rssi - snr;
13658 survey->filled = SURVEY_INFO_NOISE_DBM;
13659 filled = 1;
13660 }
13661 }
13662 }
13663
13664 if (filled)
13665 pAdapter->survey_idx = 1;
13666 else
13667 {
13668 pAdapter->survey_idx = 0;
13669 return -ENONET;
13670 }
13671
13672 return 0;
13673}
13674
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013675static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13676 struct net_device *dev,
13677 int idx, struct survey_info *survey)
13678{
13679 int ret;
13680
13681 vos_ssr_protect(__func__);
13682 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13683 vos_ssr_unprotect(__func__);
13684
13685 return ret;
13686}
13687
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013688/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013689 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013690 * this is called when cfg80211 driver resume
13691 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13692 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013693int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013694{
13695 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13696 hdd_adapter_t *pAdapter;
13697 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13698 VOS_STATUS status = VOS_STATUS_SUCCESS;
13699
13700 ENTER();
13701
13702 if ( NULL == pHddCtx )
13703 {
13704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13705 "%s: HddCtx validation failed", __func__);
13706 return 0;
13707 }
13708
13709 if (pHddCtx->isLogpInProgress)
13710 {
13711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13712 "%s: LOGP in Progress. Ignore!!!", __func__);
13713 return 0;
13714 }
13715
Mihir Shete18156292014-03-11 15:38:30 +053013716 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013717 {
13718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13719 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13720 return 0;
13721 }
13722
13723 spin_lock(&pHddCtx->schedScan_lock);
13724 pHddCtx->isWiphySuspended = FALSE;
13725 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13726 {
13727 spin_unlock(&pHddCtx->schedScan_lock);
13728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13729 "%s: Return resume is not due to PNO indication", __func__);
13730 return 0;
13731 }
13732 // Reset flag to avoid updatating cfg80211 data old results again
13733 pHddCtx->isSchedScanUpdatePending = FALSE;
13734 spin_unlock(&pHddCtx->schedScan_lock);
13735
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013736
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013737 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13738
13739 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13740 {
13741 pAdapter = pAdapterNode->pAdapter;
13742 if ( (NULL != pAdapter) &&
13743 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13744 {
13745 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013746 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13748 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013749 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013750 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013751 {
13752 /* Acquire wakelock to handle the case where APP's tries to
13753 * suspend immediately after updating the scan results. Whis
13754 * results in app's is in suspended state and not able to
13755 * process the connect request to AP
13756 */
13757 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013758 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013759 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013760
13761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13762 "%s : cfg80211 scan result database updated", __func__);
13763
13764 return 0;
13765
13766 }
13767 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13768 pAdapterNode = pNext;
13769 }
13770
13771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13772 "%s: Failed to find Adapter", __func__);
13773 return 0;
13774}
13775
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013776int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13777{
13778 int ret;
13779
13780 vos_ssr_protect(__func__);
13781 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13782 vos_ssr_unprotect(__func__);
13783
13784 return ret;
13785}
13786
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013787/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013788 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013789 * this is called when cfg80211 driver suspends
13790 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013791int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013792 struct cfg80211_wowlan *wow)
13793{
13794 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13795
13796 ENTER();
13797 if (NULL == pHddCtx)
13798 {
13799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13800 "%s: HddCtx validation failed", __func__);
13801 return 0;
13802 }
13803
13804 pHddCtx->isWiphySuspended = TRUE;
13805
13806 EXIT();
13807
13808 return 0;
13809}
13810
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013811int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13812 struct cfg80211_wowlan *wow)
13813{
13814 int ret;
13815
13816 vos_ssr_protect(__func__);
13817 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13818 vos_ssr_unprotect(__func__);
13819
13820 return ret;
13821}
Jeff Johnson295189b2012-06-20 16:38:30 -070013822/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013824{
13825 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13826 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13827 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13828 .change_station = wlan_hdd_change_station,
13829#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13830 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13831 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13832 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013833#else
13834 .start_ap = wlan_hdd_cfg80211_start_ap,
13835 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13836 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013837#endif
13838 .change_bss = wlan_hdd_cfg80211_change_bss,
13839 .add_key = wlan_hdd_cfg80211_add_key,
13840 .get_key = wlan_hdd_cfg80211_get_key,
13841 .del_key = wlan_hdd_cfg80211_del_key,
13842 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 .scan = wlan_hdd_cfg80211_scan,
13847 .connect = wlan_hdd_cfg80211_connect,
13848 .disconnect = wlan_hdd_cfg80211_disconnect,
13849 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13850 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13851 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13852 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13853 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13855 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013856 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13858 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13859 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13860 .set_txq_params = wlan_hdd_set_txq_params,
13861#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 .get_station = wlan_hdd_cfg80211_get_station,
13863 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13864 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013865 .add_station = wlan_hdd_cfg80211_add_station,
13866#ifdef FEATURE_WLAN_LFR
13867 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13868 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13869 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13870#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013871#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13872 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13873#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013874#ifdef FEATURE_WLAN_TDLS
13875 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13876 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13877#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013878#ifdef WLAN_FEATURE_GTK_OFFLOAD
13879 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13880#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013881#ifdef FEATURE_WLAN_SCAN_PNO
13882 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13883 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13884#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013885 .resume = wlan_hdd_cfg80211_resume_wlan,
13886 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013887 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013888#ifdef WLAN_NL80211_TESTMODE
13889 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13890#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013891 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013892};
13893