blob: 6242936e8e81940b22e194f45658cf1bbc5300b1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530168static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700169{
170 WLAN_CIPHER_SUITE_WEP40,
171 WLAN_CIPHER_SUITE_WEP104,
172 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800173#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700174#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
175 WLAN_CIPHER_SUITE_KRK,
176 WLAN_CIPHER_SUITE_CCMP,
177#else
178 WLAN_CIPHER_SUITE_CCMP,
179#endif
180#ifdef FEATURE_WLAN_WAPI
181 WLAN_CIPHER_SUITE_SMS4,
182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700183#ifdef WLAN_FEATURE_11W
184 WLAN_CIPHER_SUITE_AES_CMAC,
185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700186};
187
188static inline int is_broadcast_ether_addr(const u8 *addr)
189{
190 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
191 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
192}
193
194static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530195{
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 HDD2GHZCHAN(2412, 1, 0) ,
197 HDD2GHZCHAN(2417, 2, 0) ,
198 HDD2GHZCHAN(2422, 3, 0) ,
199 HDD2GHZCHAN(2427, 4, 0) ,
200 HDD2GHZCHAN(2432, 5, 0) ,
201 HDD2GHZCHAN(2437, 6, 0) ,
202 HDD2GHZCHAN(2442, 7, 0) ,
203 HDD2GHZCHAN(2447, 8, 0) ,
204 HDD2GHZCHAN(2452, 9, 0) ,
205 HDD2GHZCHAN(2457, 10, 0) ,
206 HDD2GHZCHAN(2462, 11, 0) ,
207 HDD2GHZCHAN(2467, 12, 0) ,
208 HDD2GHZCHAN(2472, 13, 0) ,
209 HDD2GHZCHAN(2484, 14, 0) ,
210};
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
213{
214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2437, 6, 0) ,
216 HDD2GHZCHAN(2462, 11, 0) ,
217};
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219static struct ieee80211_channel hdd_channels_5_GHZ[] =
220{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700221 HDD5GHZCHAN(4920, 240, 0) ,
222 HDD5GHZCHAN(4940, 244, 0) ,
223 HDD5GHZCHAN(4960, 248, 0) ,
224 HDD5GHZCHAN(4980, 252, 0) ,
225 HDD5GHZCHAN(5040, 208, 0) ,
226 HDD5GHZCHAN(5060, 212, 0) ,
227 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5180, 36, 0) ,
229 HDD5GHZCHAN(5200, 40, 0) ,
230 HDD5GHZCHAN(5220, 44, 0) ,
231 HDD5GHZCHAN(5240, 48, 0) ,
232 HDD5GHZCHAN(5260, 52, 0) ,
233 HDD5GHZCHAN(5280, 56, 0) ,
234 HDD5GHZCHAN(5300, 60, 0) ,
235 HDD5GHZCHAN(5320, 64, 0) ,
236 HDD5GHZCHAN(5500,100, 0) ,
237 HDD5GHZCHAN(5520,104, 0) ,
238 HDD5GHZCHAN(5540,108, 0) ,
239 HDD5GHZCHAN(5560,112, 0) ,
240 HDD5GHZCHAN(5580,116, 0) ,
241 HDD5GHZCHAN(5600,120, 0) ,
242 HDD5GHZCHAN(5620,124, 0) ,
243 HDD5GHZCHAN(5640,128, 0) ,
244 HDD5GHZCHAN(5660,132, 0) ,
245 HDD5GHZCHAN(5680,136, 0) ,
246 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800247#ifdef FEATURE_WLAN_CH144
248 HDD5GHZCHAN(5720,144, 0) ,
249#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDD5GHZCHAN(5745,149, 0) ,
251 HDD5GHZCHAN(5765,153, 0) ,
252 HDD5GHZCHAN(5785,157, 0) ,
253 HDD5GHZCHAN(5805,161, 0) ,
254 HDD5GHZCHAN(5825,165, 0) ,
255};
256
257static struct ieee80211_rate g_mode_rates[] =
258{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530259 HDD_G_MODE_RATETAB(10, 0x1, 0),
260 HDD_G_MODE_RATETAB(20, 0x2, 0),
261 HDD_G_MODE_RATETAB(55, 0x4, 0),
262 HDD_G_MODE_RATETAB(110, 0x8, 0),
263 HDD_G_MODE_RATETAB(60, 0x10, 0),
264 HDD_G_MODE_RATETAB(90, 0x20, 0),
265 HDD_G_MODE_RATETAB(120, 0x40, 0),
266 HDD_G_MODE_RATETAB(180, 0x80, 0),
267 HDD_G_MODE_RATETAB(240, 0x100, 0),
268 HDD_G_MODE_RATETAB(360, 0x200, 0),
269 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271};
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273static struct ieee80211_rate a_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
283};
284
285static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
286{
287 .channels = hdd_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
303
Jeff Johnson295189b2012-06-20 16:38:30 -0700304static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
305{
306 .channels = hdd_social_channels_2_4_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
308 .band = IEEE80211_BAND_2GHZ,
309 .bitrates = g_mode_rates,
310 .n_bitrates = g_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
316 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
317 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
318 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
319 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
320 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
321};
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
324{
325 .channels = hdd_channels_5_GHZ,
326 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
327 .band = IEEE80211_BAND_5GHZ,
328 .bitrates = a_mode_rates,
329 .n_bitrates = a_mode_rates_size,
330 .ht_cap.ht_supported = 1,
331 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
332 | IEEE80211_HT_CAP_GRN_FLD
333 | IEEE80211_HT_CAP_DSSSCCK40
334 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
335 | IEEE80211_HT_CAP_SGI_40
336 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
337 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
338 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
339 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
340 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
341 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
342};
343
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530344/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 TX/RX direction for each kind of interface */
346static const struct ieee80211_txrx_stypes
347wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
348 [NL80211_IFTYPE_STATION] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
427/* By default, only single channel concurrency is allowed */
428static struct ieee80211_iface_combination
429wlan_hdd_iface_combination = {
430 .limits = wlan_hdd_iface_limit,
431 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800432 /*
433 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
434 * and p2p0 interfaces during driver init
435 * Some vendors create separate interface for P2P operations.
436 * wlan0: STA interface
437 * p2p0: P2P Device interface, action frames goes
438 * through this interface.
439 * p2p-xx: P2P interface, After GO negotiation this interface is
440 * created for p2p operations(GO/CLIENT interface).
441 */
442 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800443 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
444 .beacon_int_infra_match = false,
445};
446#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448static struct cfg80211_ops wlan_hdd_cfg80211_ops;
449
450/* Data rate 100KBPS based on IE Index */
451struct index_data_rate_type
452{
453 v_U8_t beacon_rate_index;
454 v_U16_t supported_rate[4];
455};
456
457/* 11B, 11G Rate table include Basic rate and Extended rate
458 The IDX field is the rate index
459 The HI field is the rate when RSSI is strong or being ignored
460 (in this case we report actual rate)
461 The MID field is the rate when RSSI is moderate
462 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
463 The LO field is the rate when RSSI is low
464 (in this case we don't report rates, actual current rate used)
465 */
466static const struct
467{
468 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700470} supported_data_rate[] =
471{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700472/* IDX HI HM LM LO (RSSI-based index */
473 {2, { 10, 10, 10, 0}},
474 {4, { 20, 20, 10, 0}},
475 {11, { 55, 20, 10, 0}},
476 {12, { 60, 55, 20, 0}},
477 {18, { 90, 55, 20, 0}},
478 {22, {110, 55, 20, 0}},
479 {24, {120, 90, 60, 0}},
480 {36, {180, 120, 60, 0}},
481 {44, {220, 180, 60, 0}},
482 {48, {240, 180, 90, 0}},
483 {66, {330, 180, 90, 0}},
484 {72, {360, 240, 90, 0}},
485 {96, {480, 240, 120, 0}},
486 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700487};
488
489/* MCS Based rate table */
490static struct index_data_rate_type supported_mcs_rate[] =
491{
492/* MCS L20 L40 S20 S40 */
493 {0, {65, 135, 72, 150}},
494 {1, {130, 270, 144, 300}},
495 {2, {195, 405, 217, 450}},
496 {3, {260, 540, 289, 600}},
497 {4, {390, 810, 433, 900}},
498 {5, {520, 1080, 578, 1200}},
499 {6, {585, 1215, 650, 1350}},
500 {7, {650, 1350, 722, 1500}}
501};
502
Leo Chang6f8870f2013-03-26 18:11:36 -0700503#ifdef WLAN_FEATURE_11AC
504
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530505#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700506
507struct index_vht_data_rate_type
508{
509 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510 v_U16_t supported_VHT80_rate[2];
511 v_U16_t supported_VHT40_rate[2];
512 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700513};
514
515typedef enum
516{
517 DATA_RATE_11AC_MAX_MCS_7,
518 DATA_RATE_11AC_MAX_MCS_8,
519 DATA_RATE_11AC_MAX_MCS_9,
520 DATA_RATE_11AC_MAX_MCS_NA
521} eDataRate11ACMaxMcs;
522
523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540extern struct net_device_ops net_ops_struct;
541
Leo Chang9056f462013-08-01 19:21:11 -0700542#ifdef WLAN_NL80211_TESTMODE
543enum wlan_hdd_tm_attr
544{
545 WLAN_HDD_TM_ATTR_INVALID = 0,
546 WLAN_HDD_TM_ATTR_CMD = 1,
547 WLAN_HDD_TM_ATTR_DATA = 2,
548 WLAN_HDD_TM_ATTR_TYPE = 3,
549 /* keep last */
550 WLAN_HDD_TM_ATTR_AFTER_LAST,
551 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
552};
553
554enum wlan_hdd_tm_cmd
555{
556 WLAN_HDD_TM_CMD_WLAN_HB = 1,
557};
558
559#define WLAN_HDD_TM_DATA_MAX_LEN 5000
560
561static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
562{
563 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
564 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
565 .len = WLAN_HDD_TM_DATA_MAX_LEN },
566};
567#endif /* WLAN_NL80211_TESTMODE */
568
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800569#ifdef FEATURE_WLAN_CH_AVOID
570/*
571 * FUNCTION: wlan_hdd_send_avoid_freq_event
572 * This is called when wlan driver needs to send vendor specific
573 * avoid frequency range event to userspace
574 */
575int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
576 tHddAvoidFreqList *pAvoidFreqList)
577{
578 struct sk_buff *vendor_event;
579
580 ENTER();
581
582 if (!pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 "%s: HDD context is null", __func__);
586 return -1;
587 }
588
589 if (!pAvoidFreqList)
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 "%s: pAvoidFreqList is null", __func__);
593 return -1;
594 }
595
596 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
597 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530598 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800599 GFP_KERNEL);
600 if (!vendor_event)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: cfg80211_vendor_event_alloc failed", __func__);
604 return -1;
605 }
606
607 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
608 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
609
610 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
611
612 EXIT();
613 return 0;
614}
615#endif /* FEATURE_WLAN_CH_AVOID */
616
Sunil Duttc69bccb2014-05-26 21:30:20 +0530617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
618
619static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
620 struct sk_buff *vendor_event)
621{
622 if (nla_put_u8(vendor_event,
623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
624 stats->rate.preamble) ||
625 nla_put_u8(vendor_event,
626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
627 stats->rate.nss) ||
628 nla_put_u8(vendor_event,
629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
630 stats->rate.bw) ||
631 nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
633 stats->rate.rateMcsIdx) ||
634 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
635 stats->rate.bitrate ) ||
636 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
637 stats->txMpdu ) ||
638 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
639 stats->rxMpdu ) ||
640 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
641 stats->mpduLost ) ||
642 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
643 stats->retries) ||
644 nla_put_u32(vendor_event,
645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
646 stats->retriesShort ) ||
647 nla_put_u32(vendor_event,
648 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
649 stats->retriesLong))
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("QCA_WLAN_VENDOR_ATTR put fail"));
653 return FALSE;
654 }
655 return TRUE;
656}
657
658static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
659 struct sk_buff *vendor_event)
660{
661 u32 i = 0;
662 struct nlattr *rateInfo;
663 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
664 stats->type) ||
665 nla_put(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
667 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
668 nla_put_u32(vendor_event,
669 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
670 stats->capabilities) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
673 stats->numRate))
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("QCA_WLAN_VENDOR_ATTR put fail"));
677 goto error;
678 }
679
680 rateInfo = nla_nest_start(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
682 for (i = 0; i < stats->numRate; i++)
683 {
684 struct nlattr *rates;
685 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
686 stats->rateStats +
687 (i * sizeof(tSirWifiRateStat)));
688 rates = nla_nest_start(vendor_event, i);
689
690 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR,
693 FL("QCA_WLAN_VENDOR_ATTR put fail"));
694 return FALSE;
695 }
696 nla_nest_end(vendor_event, rates);
697 }
698 nla_nest_end(vendor_event, rateInfo);
699
700 return TRUE;
701error:
702 return FALSE;
703}
704
705static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
706 struct sk_buff *vendor_event)
707{
708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
709 stats->ac ) ||
710 nla_put_u32(vendor_event,
711 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
712 stats->txMpdu ) ||
713 nla_put_u32(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
715 stats->rxMpdu ) ||
716 nla_put_u32(vendor_event,
717 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
718 stats->txMcast ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
721 stats->rxMcast ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
724 stats->rxAmpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
727 stats->txAmpdu ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
730 stats->mpduLost )||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
733 stats->retries ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
736 stats->retriesShort ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
739 stats->retriesLong ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
742 stats->contentionTimeMin ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
745 stats->contentionTimeMax ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
748 stats->contentionTimeAvg ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
751 stats->contentionNumSamples ))
752 {
753 hddLog(VOS_TRACE_LEVEL_ERROR,
754 FL("QCA_WLAN_VENDOR_ATTR put fail") );
755 return FALSE;
756 }
757 return TRUE;
758}
759
760static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
761 struct sk_buff *vendor_event)
762{
763 if (nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
765 nla_put(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
767 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
770 stats->state ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
773 stats->roaming ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
776 stats->capabilities ) ||
777 nla_put(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
779 strlen(stats->ssid), stats->ssid) ||
780 nla_put(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
782 WNI_CFG_BSSID_LEN, stats->bssid) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
785 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
788 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
789 )
790 {
791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("QCA_WLAN_VENDOR_ATTR put fail") );
793 return FALSE;
794 }
795 return TRUE;
796}
797
798static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
799 struct sk_buff *vendor_event)
800{
801 int i = 0;
802 struct nlattr *wmmInfo;
803 if (FALSE == put_wifi_interface_info(
804 &pWifiIfaceStat->info,
805 vendor_event))
806 {
807 hddLog(VOS_TRACE_LEVEL_ERROR,
808 FL("QCA_WLAN_VENDOR_ATTR put fail") );
809 return FALSE;
810
811 }
812
813 if (nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
815 pWifiIfaceStat->beaconRx) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
818 pWifiIfaceStat->mgmtRx) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
821 pWifiIfaceStat->mgmtActionRx) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
824 pWifiIfaceStat->mgmtActionTx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
827 pWifiIfaceStat->rssiMgmt) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
830 pWifiIfaceStat->rssiData) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
833 pWifiIfaceStat->rssiAck))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 return FALSE;
838 }
839
840 wmmInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
842 for (i = 0; i < WIFI_AC_MAX; i++)
843 {
844 struct nlattr *wmmStats;
845 wmmStats = nla_nest_start(vendor_event, i);
846 if (FALSE == put_wifi_wmm_ac_stat(
847 &pWifiIfaceStat->AccessclassStats[i],
848 vendor_event))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
852 return FALSE;
853 }
854
855 nla_nest_end(vendor_event, wmmStats);
856 }
857 nla_nest_end(vendor_event, wmmInfo);
858 return TRUE;
859}
860
861static tSirWifiInterfaceMode
862 hdd_map_device_to_ll_iface_mode ( int deviceMode )
863{
864 switch (deviceMode)
865 {
866 case WLAN_HDD_INFRA_STATION:
867 return WIFI_INTERFACE_STA;
868 case WLAN_HDD_SOFTAP:
869 return WIFI_INTERFACE_SOFTAP;
870 case WLAN_HDD_P2P_CLIENT:
871 return WIFI_INTERFACE_P2P_CLIENT;
872 case WLAN_HDD_P2P_GO:
873 return WIFI_INTERFACE_P2P_GO;
874 case WLAN_HDD_IBSS:
875 return WIFI_INTERFACE_IBSS;
876 default:
877 /* Return Interface Mode as STA for all the unsupported modes */
878 return WIFI_INTERFACE_STA;
879 }
880}
881
882static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
883 tpSirWifiInterfaceInfo pInfo)
884{
885 v_U8_t *staMac = NULL;
886 hdd_station_ctx_t *pHddStaCtx;
887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
888 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
889
890 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
891
892 vos_mem_copy(pInfo->macAddr,
893 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
894
895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
898 {
899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
900 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
901 {
902 pInfo->state = WIFI_DISCONNECTED;
903 }
904 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
905 {
906 hddLog(VOS_TRACE_LEVEL_ERROR,
907 "%s: Session ID %d, Connection is in progress", __func__,
908 pAdapter->sessionId);
909 pInfo->state = WIFI_ASSOCIATING;
910 }
911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
913 {
914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: client " MAC_ADDRESS_STR
917 " is in the middle of WPS/EAPOL exchange.", __func__,
918 MAC_ADDR_ARRAY(staMac));
919 pInfo->state = WIFI_AUTHENTICATING;
920 }
921 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
922 {
923 pInfo->state = WIFI_ASSOCIATED;
924 vos_mem_copy(pInfo->bssid,
925 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
926 vos_mem_copy(pInfo->ssid,
927 pHddStaCtx->conn_info.SSID.SSID.ssId,
928 pHddStaCtx->conn_info.SSID.SSID.length);
929 //NULL Terminate the string.
930 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
931 }
932 }
933 vos_mem_copy(pInfo->countryStr,
934 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
935
936 vos_mem_copy(pInfo->apCountryStr,
937 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
938
939 return TRUE;
940}
941
942/*
943 * hdd_link_layer_process_peer_stats () - This function is called after
944 * receiving Link Layer Peer statistics from FW.This function converts
945 * the firmware data to the NL data and sends the same to the kernel/upper
946 * layers.
947 */
948static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
949 v_VOID_t *pData)
950{
951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
952 tpSirWifiRateStat pWifiRateStat;
953 tpSirWifiPeerStat pWifiPeerStat;
954 tpSirWifiPeerInfo pWifiPeerInfo;
955 struct nlattr *peerInfo;
956 struct sk_buff *vendor_event;
957 int status, i;
958
959 status = wlan_hdd_validate_context(pHddCtx);
960 if (0 != status)
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("HDD context is not valid") );
964 return;
965 }
966
967 pWifiPeerStat = (tpSirWifiPeerStat) pData;
968
969 hddLog(VOS_TRACE_LEVEL_INFO,
970 "LL_STATS_PEER_ALL : numPeers %u",
971 pWifiPeerStat->numPeers);
972 {
973 for (i = 0; i < pWifiPeerStat->numPeers; i++)
974 {
975 pWifiPeerInfo = (tpSirWifiPeerInfo)
976 ((uint8 *)pWifiPeerStat->peerInfo +
977 ( i * sizeof(tSirWifiPeerInfo)));
978
979 hddLog(VOS_TRACE_LEVEL_INFO,
980 " %d) LL_STATS Channel Stats "
981 " Peer Type %u "
982 " peerMacAddress %pM "
983 " capabilities 0x%x "
984 " numRate %u ",
985 i,
986 pWifiPeerInfo->type,
987 pWifiPeerInfo->peerMacAddress,
988 pWifiPeerInfo->capabilities,
989 pWifiPeerInfo->numRate);
990 {
991 int j;
992 for (j = 0; j < pWifiPeerInfo->numRate; j++)
993 {
994 pWifiRateStat = (tpSirWifiRateStat)
995 ((tANI_U8 *) pWifiPeerInfo->rateStats +
996 ( j * sizeof(tSirWifiRateStat)));
997
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 " peer Rate Stats "
1000 " preamble %u "
1001 " nss %u "
1002 " bw %u "
1003 " rateMcsIdx %u "
1004 " reserved %u "
1005 " bitrate %u "
1006 " txMpdu %u "
1007 " rxMpdu %u "
1008 " mpduLost %u "
1009 " retries %u "
1010 " retriesShort %u "
1011 " retriesLong %u",
1012 pWifiRateStat->rate.preamble,
1013 pWifiRateStat->rate.nss,
1014 pWifiRateStat->rate.bw,
1015 pWifiRateStat->rate.rateMcsIdx,
1016 pWifiRateStat->rate.reserved,
1017 pWifiRateStat->rate.bitrate,
1018 pWifiRateStat->txMpdu,
1019 pWifiRateStat->rxMpdu,
1020 pWifiRateStat->mpduLost,
1021 pWifiRateStat->retries,
1022 pWifiRateStat->retriesShort,
1023 pWifiRateStat->retriesLong);
1024 }
1025 }
1026 }
1027 }
1028
1029 /*
1030 * Allocate a size of 4096 for the peer stats comprising
1031 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1032 * sizeof (tSirWifiRateStat).Each field is put with an
1033 * NL attribute.The size of 4096 is considered assuming
1034 * that number of rates shall not exceed beyond 50 with
1035 * the sizeof (tSirWifiRateStat) being 32.
1036 */
1037 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1038 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1039 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1040 GFP_KERNEL);
1041 if (!vendor_event)
1042 {
1043 hddLog(VOS_TRACE_LEVEL_ERROR,
1044 "%s: cfg80211_vendor_event_alloc failed",
1045 __func__);
1046 return;
1047 }
1048 if (nla_put_u32(vendor_event,
1049 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1050 pWifiPeerStat->numPeers))
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1054 kfree_skb(vendor_event);
1055 return;
1056 }
1057
1058 peerInfo = nla_nest_start(vendor_event,
1059 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1060
1061 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1062 pWifiPeerStat->peerInfo);
1063
1064 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1065 {
1066 struct nlattr *peers = nla_nest_start(vendor_event, i);
1067 int numRate = pWifiPeerInfo->numRate;
1068
1069 if (FALSE == put_wifi_peer_info(
1070 pWifiPeerInfo, vendor_event))
1071 {
1072 hddLog(VOS_TRACE_LEVEL_ERROR,
1073 "%s: put_wifi_peer_info put fail", __func__);
1074 kfree_skb(vendor_event);
1075 return;
1076 }
1077
1078 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1079 pWifiPeerStat->peerInfo +
1080 (i * sizeof(tSirWifiPeerInfo)) +
1081 (numRate * sizeof (tSirWifiRateStat)));
1082 nla_nest_end(vendor_event, peers);
1083 }
1084 nla_nest_end(vendor_event, peerInfo);
1085 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1086}
1087
1088/*
1089 * hdd_link_layer_process_iface_stats () - This function is called after
1090 * receiving Link Layer Interface statistics from FW.This function converts
1091 * the firmware data to the NL data and sends the same to the kernel/upper
1092 * layers.
1093 */
1094static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1095 v_VOID_t *pData)
1096{
1097 tpSirWifiIfaceStat pWifiIfaceStat;
1098 struct sk_buff *vendor_event;
1099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1100 int status;
1101
1102 status = wlan_hdd_validate_context(pHddCtx);
1103 if (0 != status)
1104 {
1105 hddLog(VOS_TRACE_LEVEL_ERROR,
1106 FL("HDD context is not valid") );
1107 return;
1108 }
1109 /*
1110 * Allocate a size of 4096 for the interface stats comprising
1111 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1112 * assuming that all these fit with in the limit.Please take
1113 * a call on the limit based on the data requirements on
1114 * interface statistics.
1115 */
1116 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1117 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1118 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1119 GFP_KERNEL);
1120 if (!vendor_event)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR,
1123 FL("cfg80211_vendor_event_alloc failed") );
1124 return;
1125 }
1126
1127 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1128
1129 hddLog(VOS_TRACE_LEVEL_INFO,
1130 "WMI_LINK_STATS_IFACE Data");
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 "LL_STATS_IFACE: "
1134 " Mode %u "
1135 " MAC %pM "
1136 " State %u "
1137 " Roaming %u "
1138 " capabilities 0x%x "
1139 " SSID %s "
1140 " BSSID %pM",
1141 pWifiIfaceStat->info.mode,
1142 pWifiIfaceStat->info.macAddr,
1143 pWifiIfaceStat->info.state,
1144 pWifiIfaceStat->info.roaming,
1145 pWifiIfaceStat->info.capabilities,
1146 pWifiIfaceStat->info.ssid,
1147 pWifiIfaceStat->info.bssid);
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 " AP country str: %c%c%c",
1151 pWifiIfaceStat->info.apCountryStr[0],
1152 pWifiIfaceStat->info.apCountryStr[1],
1153 pWifiIfaceStat->info.apCountryStr[2]);
1154
1155
1156 hddLog(VOS_TRACE_LEVEL_INFO,
1157 " Country Str Association: %c%c%c",
1158 pWifiIfaceStat->info.countryStr[0],
1159 pWifiIfaceStat->info.countryStr[1],
1160 pWifiIfaceStat->info.countryStr[2]);
1161
1162 hddLog(VOS_TRACE_LEVEL_INFO,
1163 " beaconRx %u "
1164 " mgmtRx %u "
1165 " mgmtActionRx %u "
1166 " mgmtActionTx %u "
1167 " rssiMgmt %u "
1168 " rssiData %u "
1169 " rssiAck %u",
1170 pWifiIfaceStat->beaconRx,
1171 pWifiIfaceStat->mgmtRx,
1172 pWifiIfaceStat->mgmtActionRx,
1173 pWifiIfaceStat->mgmtActionTx,
1174 pWifiIfaceStat->rssiMgmt,
1175 pWifiIfaceStat->rssiData,
1176 pWifiIfaceStat->rssiAck );
1177
1178
1179 {
1180 int i;
1181 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_INFO,
1184
1185 " %d) LL_STATS IFACE: "
1186 " ac: %u txMpdu: %u "
1187 " rxMpdu: %u txMcast: %u "
1188 " rxMcast: %u rxAmpdu: %u "
1189 " txAmpdu: %u mpduLost: %u "
1190 " retries: %u retriesShort: %u "
1191 " retriesLong: %u contentionTimeMin: %u "
1192 " contentionTimeMax: %u contentionTimeAvg: %u "
1193 " contentionNumSamples: %u",
1194 i,
1195 pWifiIfaceStat->AccessclassStats[i].ac,
1196 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1197 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1198 pWifiIfaceStat->AccessclassStats[i].txMcast,
1199 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1200 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1201 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1202 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1203 pWifiIfaceStat->AccessclassStats[i].retries,
1204 pWifiIfaceStat->
1205 AccessclassStats[i].retriesShort,
1206 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1207 pWifiIfaceStat->
1208 AccessclassStats[i].contentionTimeMin,
1209 pWifiIfaceStat->
1210 AccessclassStats[i].contentionTimeMax,
1211 pWifiIfaceStat->
1212 AccessclassStats[i].contentionTimeAvg,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].contentionNumSamples);
1215
1216 }
1217 }
1218
1219 if (FALSE == hdd_get_interface_info( pAdapter,
1220 &pWifiIfaceStat->info))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 FL("hdd_get_interface_info get fail") );
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1229 vendor_event))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("put_wifi_iface_stats fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1237}
1238
1239/*
1240 * hdd_link_layer_process_radio_stats () - This function is called after
1241 * receiving Link Layer Radio statistics from FW.This function converts
1242 * the firmware data to the NL data and sends the same to the kernel/upper
1243 * layers.
1244 */
1245static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1246 v_VOID_t *pData)
1247{
1248 int status, i;
1249 tpSirWifiRadioStat pWifiRadioStat;
1250 tpSirWifiChannelStats pWifiChannelStats;
1251 struct sk_buff *vendor_event;
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1253 struct nlattr *chList;
1254
1255 status = wlan_hdd_validate_context(pHddCtx);
1256 if (0 != status)
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("HDD context is not valid") );
1260 return;
1261 }
1262 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1263
1264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 "LL_STATS_RADIO"
1266 " radio is %d onTime is %u "
1267 " txTime is %u rxTime is %u "
1268 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301269 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 " onTimePnoScan is %u onTimeHs20 is %u "
1271 " numChannels is %u",
1272 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1273 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1274 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301275 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301276 pWifiRadioStat->onTimeRoamScan,
1277 pWifiRadioStat->onTimePnoScan,
1278 pWifiRadioStat->onTimeHs20,
1279 pWifiRadioStat->numChannels);
1280 /*
1281 * Allocate a size of 4096 for the Radio stats comprising
1282 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1283 * (tSirWifiChannelStats).Each channel data is put with an
1284 * NL attribute.The size of 4096 is considered assuming that
1285 * number of channels shall not exceed beyond 60 with the
1286 * sizeof (tSirWifiChannelStats) being 24 bytes.
1287 */
1288
1289 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1290 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1291 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1292 GFP_KERNEL);
1293
1294 if (!vendor_event)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 FL("cfg80211_vendor_event_alloc failed") );
1298 return;
1299 }
1300
1301 if (nla_put_u32(vendor_event,
1302 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1303 pWifiRadioStat->radio) ||
1304 nla_put_u32(vendor_event,
1305 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1306 pWifiRadioStat->onTime) ||
1307 nla_put_u32(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1309 pWifiRadioStat->txTime) ||
1310 nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1312 pWifiRadioStat->rxTime) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1315 pWifiRadioStat->onTimeScan) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1318 pWifiRadioStat->onTimeNbd) ||
1319 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1321 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1324 pWifiRadioStat->onTimeRoamScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1327 pWifiRadioStat->onTimePnoScan) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1330 pWifiRadioStat->onTimeHs20) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1333 pWifiRadioStat->numChannels))
1334 {
1335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1337 kfree_skb(vendor_event);
1338 return ;
1339 }
1340
1341 chList = nla_nest_start(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1343 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1344 {
1345 struct nlattr *chInfo;
1346
1347 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1348 pWifiRadioStat->channels +
1349 (i * sizeof(tSirWifiChannelStats)));
1350
1351 hddLog(VOS_TRACE_LEVEL_INFO,
1352 " %d) Channel Info"
1353 " width is %u "
1354 " CenterFreq %u "
1355 " CenterFreq0 %u "
1356 " CenterFreq1 %u "
1357 " onTime %u "
1358 " ccaBusyTime %u",
1359 i,
1360 pWifiChannelStats->channel.width,
1361 pWifiChannelStats->channel.centerFreq,
1362 pWifiChannelStats->channel.centerFreq0,
1363 pWifiChannelStats->channel.centerFreq1,
1364 pWifiChannelStats->onTime,
1365 pWifiChannelStats->ccaBusyTime);
1366
1367
1368 chInfo = nla_nest_start(vendor_event, i);
1369
1370 if (nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1372 pWifiChannelStats->channel.width) ||
1373 nla_put_u32(vendor_event,
1374 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1375 pWifiChannelStats->channel.centerFreq) ||
1376 nla_put_u32(vendor_event,
1377 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1378 pWifiChannelStats->channel.centerFreq0) ||
1379 nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1381 pWifiChannelStats->channel.centerFreq1) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1384 pWifiChannelStats->onTime) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1387 pWifiChannelStats->ccaBusyTime))
1388 {
1389 hddLog(VOS_TRACE_LEVEL_ERROR,
1390 FL("cfg80211_vendor_event_alloc failed") );
1391 kfree_skb(vendor_event);
1392 return ;
1393 }
1394 nla_nest_end(vendor_event, chInfo);
1395 }
1396 nla_nest_end(vendor_event, chList);
1397
1398 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1399 return;
1400}
1401
1402/*
1403 * hdd_link_layer_stats_ind_callback () - This function is called after
1404 * receiving Link Layer indications from FW.This callback converts the firmware
1405 * data to the NL data and send the same to the kernel/upper layers.
1406 */
1407static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1408 int indType,
1409 void *pRsp )
1410{
1411 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCtx;
1412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1413 int status;
1414
1415 status = wlan_hdd_validate_context(pHddCtx);
1416
1417 if (0 != status)
1418 {
1419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 FL("HDD context is not valid"));
1421 return;
1422 }
1423
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1425 "%s: Link Layer Indication indType: %d", __func__, indType);
1426 switch (indType)
1427 {
1428 case SIR_HAL_LL_STATS_RESULTS_RSP:
1429 {
1430 tpSirLLStatsResults linkLayerStatsResults =
1431 (tpSirLLStatsResults)pRsp;
1432
1433
1434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1436 hddLog(VOS_TRACE_LEVEL_INFO,
1437 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1438 linkLayerStatsResults->paramId);
1439 hddLog(VOS_TRACE_LEVEL_INFO,
1440 "LL_STATS RESULTS RESPONSE ifaceId = %u",
1441 linkLayerStatsResults->ifaceId);
1442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "LL_STATS RESULTS RESPONSE respId = %u",
1444 linkLayerStatsResults->respId);
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1447 linkLayerStatsResults->moreResultToFollow);
1448 hddLog(VOS_TRACE_LEVEL_INFO,
1449 "LL_STATS RESULTS RESPONSE result = %p",
1450 linkLayerStatsResults->result);
1451 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1452 {
1453 hdd_link_layer_process_radio_stats(pAdapter,
1454 (v_VOID_t *)linkLayerStatsResults->result);
1455 }
1456 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1457 {
1458 hdd_link_layer_process_iface_stats(pAdapter,
1459 (v_VOID_t *)linkLayerStatsResults->result);
1460 }
1461 else if ( linkLayerStatsResults->paramId &
1462 WMI_LINK_STATS_ALL_PEER )
1463 {
1464 hdd_link_layer_process_peer_stats(pAdapter,
1465 (v_VOID_t *)linkLayerStatsResults->result);
1466 } /* WMI_LINK_STATS_ALL_PEER */
1467 else
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
1470 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1471 }
1472
1473 break;
1474 }
1475 default:
1476 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1477 break;
1478 }
1479 return;
1480}
1481
1482const struct
1483nla_policy
1484qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1485{
1486 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1487 { .type = NLA_U32 },
1488 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1489 { .type = NLA_U32 },
1490};
1491
1492static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1493 struct wireless_dev *wdev,
1494 void *data,
1495 int data_len)
1496{
1497 int status;
1498 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
1499 tpSirLLStatsSetReq pLinkLayerStatsSetReq;
1500 struct net_device *dev = wdev->netdev;
1501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1503
1504 status = wlan_hdd_validate_context(pHddCtx);
1505 if (0 != status)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("HDD context is not valid"));
1509 return -EINVAL;
1510 }
1511
1512 if (NULL == pAdapter)
1513 {
1514 hddLog(VOS_TRACE_LEVEL_ERROR,
1515 FL("HDD adapter is Null"));
1516 return -ENODEV;
1517 }
1518
1519 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1520 (struct nlattr *)data,
1521 data_len, qca_wlan_vendor_ll_set_policy))
1522 {
1523 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1524 return -EINVAL;
1525 }
1526 if (!tb_vendor
1527 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1528 {
1529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1530 return -EINVAL;
1531 }
1532 if (!tb_vendor[
1533 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1534 {
1535 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1536 return -EINVAL;
1537 }
1538 pLinkLayerStatsSetReq = vos_mem_malloc(sizeof(tSirLLStatsSetReq));
1539 if (NULL == pLinkLayerStatsSetReq)
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL(" Unable to allocate memory to pLinkLayerStatsSetReq") );
1543 return -ENOMEM;
1544 }
1545 // Shall take the request Id if the Upper layers pass. 1 For now.
1546 pLinkLayerStatsSetReq->reqId = 1;
1547
1548 pLinkLayerStatsSetReq->mpduSizeThreshold =
1549 nla_get_u32(
1550 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1551
1552 pLinkLayerStatsSetReq->aggressiveStatisticsGathering =
1553 nla_get_u32(
1554 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1555
1556 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1557 * Hence the interface staId start from 1. Hence the staId matching the
1558 * interface in the firmware is sessionId + 1.
1559 */
1560 pLinkLayerStatsSetReq->staId = pAdapter->sessionId + 1;
1561
1562
1563 hddLog(VOS_TRACE_LEVEL_INFO,
1564 "LL_STATS_SET reqId = %d",
1565 pLinkLayerStatsSetReq->reqId);
1566 hddLog(VOS_TRACE_LEVEL_INFO,
1567 "LL_STATS_SET staId = %d", pLinkLayerStatsSetReq->staId);
1568 hddLog(VOS_TRACE_LEVEL_INFO,
1569 "LL_STATS_SET mpduSizeThreshold = %d",
1570 pLinkLayerStatsSetReq->mpduSizeThreshold);
1571 hddLog(VOS_TRACE_LEVEL_INFO,
1572 "LL_STATS_SET aggressive Statistics Gathering = %d",
1573 pLinkLayerStatsSetReq->aggressiveStatisticsGathering);
1574
1575 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1576 pHddCtx->hHal,
1577 pAdapter->sessionId,
1578 hdd_link_layer_stats_ind_callback,
1579 pAdapter))
1580 {
1581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1582 "sme_SetLinkLayerStatsIndCB Failed", __func__);
1583 vos_mem_free(pLinkLayerStatsSetReq);
1584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
1588 pLinkLayerStatsSetReq))
1589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
1592 vos_mem_free(pLinkLayerStatsSetReq);
1593 return -EINVAL;
1594 }
1595
1596 pAdapter->isLinkLayerStatsSet = 1;
1597
1598 return 0;
1599}
1600
1601const struct
1602nla_policy
1603qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1604{
1605 /* Unsigned 32bit value provided by the caller issuing the GET stats
1606 * command. When reporting
1607 * the stats results, the driver uses the same value to indicate
1608 * which GET request the results
1609 * correspond to.
1610 */
1611 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1612
1613 /* Unsigned 32bit value . bit mask to identify what statistics are
1614 requested for retrieval */
1615 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1616};
1617
1618static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1619 struct wireless_dev *wdev,
1620 void *data,
1621 int data_len)
1622{
1623 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1624 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
1625 tpSirLLStatsGetReq pLinkLayerStatsGetReq;
1626 struct net_device *dev = wdev->netdev;
1627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1628 int status;
1629
1630 status = wlan_hdd_validate_context(pHddCtx);
1631 if (0 != status)
1632 {
1633 hddLog(VOS_TRACE_LEVEL_ERROR,
1634 FL("HDD context is not valid"));
1635 return -EINVAL ;
1636 }
1637
1638 if (NULL == pAdapter)
1639 {
1640 hddLog(VOS_TRACE_LEVEL_FATAL,
1641 "%s: HDD adapter is Null", __func__);
1642 return -ENODEV;
1643 }
1644
1645 if (!pAdapter->isLinkLayerStatsSet)
1646 {
1647 hddLog(VOS_TRACE_LEVEL_FATAL,
1648 "%s: isLinkLayerStatsSet : %d",
1649 __func__, pAdapter->isLinkLayerStatsSet);
1650 return -EINVAL;
1651 }
1652
1653 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1654 (struct nlattr *)data,
1655 data_len, qca_wlan_vendor_ll_get_policy))
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1658 return -EINVAL;
1659 }
1660
1661 if (!tb_vendor
1662 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1663 {
1664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1665 return -EINVAL;
1666 }
1667
1668 if (!tb_vendor
1669 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1670 {
1671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1672 return -EINVAL;
1673 }
1674
1675 pLinkLayerStatsGetReq = vos_mem_malloc(sizeof(tSirLLStatsGetReq));
1676
1677 if (NULL == pLinkLayerStatsGetReq)
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
1680 FL("Unable to allocate memory to pLinkLayerStatsGetReq"));
1681 return -ENOMEM;
1682 }
1683
1684 pLinkLayerStatsGetReq->reqId =
1685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
1687 pLinkLayerStatsGetReq->paramIdMask =
1688 nla_get_u32( tb_vendor[
1689 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1690
1691 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1692 * Hence the interface staId start from 1. Hence the staId matching the
1693 * interface in the firmware is sessionId + 1.
1694 */
1695 pLinkLayerStatsGetReq->staId = pAdapter->sessionId + 1;
1696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
1698 "LL_STATS_GET reqId = %d", pLinkLayerStatsGetReq->reqId);
1699 hddLog(VOS_TRACE_LEVEL_INFO,
1700 "LL_STATS_GET staId = %d", pLinkLayerStatsGetReq->staId);
1701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
1703 pLinkLayerStatsGetReq->paramIdMask);
1704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
1706 pLinkLayerStatsGetReq))
1707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
1710 vos_mem_free(pLinkLayerStatsGetReq);
1711 return -EINVAL;
1712 }
1713 return 0;
1714}
1715
1716const struct
1717nla_policy
1718qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1719{
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1724};
1725
1726static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1727 struct wireless_dev *wdev,
1728 void *data,
1729 int data_len)
1730{
1731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1732 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
1733 tpSirLLStatsClearReq pLinkLayerStatsClearReq;
1734 struct net_device *dev = wdev->netdev;
1735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1736 u32 statsClearReqMask;
1737 u8 stopReq;
1738 int status;
1739
1740 status = wlan_hdd_validate_context(pHddCtx);
1741 if (0 != status)
1742 {
1743 hddLog(VOS_TRACE_LEVEL_ERROR,
1744 FL("HDD context is not valid"));
1745 return -EINVAL;
1746 }
1747
1748 if (NULL == pAdapter)
1749 {
1750 hddLog(VOS_TRACE_LEVEL_FATAL,
1751 "%s: HDD adapter is Null", __func__);
1752 return -ENODEV;
1753 }
1754
1755 if (!pAdapter->isLinkLayerStatsSet)
1756 {
1757 hddLog(VOS_TRACE_LEVEL_FATAL,
1758 "%s: isLinkLayerStatsSet : %d",
1759 __func__, pAdapter->isLinkLayerStatsSet);
1760 return -EINVAL;
1761 }
1762
1763 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1764 (struct nlattr *)data,
1765 data_len, qca_wlan_vendor_ll_clr_policy))
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1768 return -EINVAL;
1769 }
1770
1771 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1772
1773 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1774 {
1775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1776 return -EINVAL;
1777
1778 }
1779
1780 pLinkLayerStatsClearReq = vos_mem_malloc(sizeof(tSirLLStatsClearReq));
1781 if (NULL == pLinkLayerStatsClearReq)
1782 {
1783 hddLog(VOS_TRACE_LEVEL_ERROR,
1784 FL("Unable to allocate memory to pLinkLayerStatsClearReq"));
1785 return -ENOMEM;
1786 }
1787
1788 statsClearReqMask = pLinkLayerStatsClearReq->statsClearReqMask =
1789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
1792 stopReq = pLinkLayerStatsClearReq->stopReq =
1793 nla_get_u8(
1794 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1795
1796 // Shall take the request Id if the Upper layers pass. 1 For now.
1797 pLinkLayerStatsClearReq->reqId = 1;
1798
1799 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1800 * Hence the interface staId start from 1. Hence the staId matching the
1801 * interface in the firmware is sessionId + 1.
1802 */
1803 pLinkLayerStatsClearReq->staId = pAdapter->sessionId + 1;
1804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
1806 "LL_STATS_CLEAR reqId = %d", pLinkLayerStatsClearReq->reqId);
1807 hddLog(VOS_TRACE_LEVEL_INFO,
1808 "LL_STATS_CLEAR staId = %d", pLinkLayerStatsClearReq->staId);
1809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
1811 pLinkLayerStatsClearReq->statsClearReqMask);
1812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
1814 pLinkLayerStatsClearReq->stopReq);
1815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
1817 pLinkLayerStatsClearReq))
1818 {
1819 struct sk_buff *temp_skbuff;
1820 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1821 2 * sizeof(u32) +
1822 NLMSG_HDRLEN);
1823
1824 if (temp_skbuff != NULL)
1825 {
1826
1827 if (nla_put_u32(temp_skbuff,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1829 statsClearReqMask) ||
1830 nla_put_u32(temp_skbuff,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1832 stopReq))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1835 kfree_skb(temp_skbuff);
1836 return -EINVAL;
1837 }
1838 /* If the ask is to stop the stats collection as part of clear
1839 * (stopReq = 1) , ensure that no further requests of get
1840 * go to the firmware by having isLinkLayerStatsSet set to 0.
1841 * However it the stopReq as part of the clear request is 0 ,
1842 * the request to get the statistics are ehonoured as in this
1843 * case the firmware is just asked to clear the statistics.
1844 */
1845 if (pLinkLayerStatsClearReq->stopReq == 1)
1846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
1851 vos_mem_free(pLinkLayerStatsClearReq);
1852 return -EINVAL;
1853}
1854#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1855
Dino Mycle6fb96c12014-06-10 11:52:40 +05301856#ifdef WLAN_FEATURE_EXTSCAN
1857static const struct nla_policy
1858wlan_hdd_extscan_config_policy
1859 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1860{
1861 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1862 { .type = NLA_U32 },
1863 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1864 { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1866 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1867 { .type = NLA_U32 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1869 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1870
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1875 { .type = NLA_U8 },
1876 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1877 { .type = NLA_U32 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1879 { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1881 { .type = NLA_U32 },
1882 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1883 { .type = NLA_U8 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1885 { .type = NLA_U8 },
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1887 { .type = NLA_U8 },
1888
1889 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1890 { .type = NLA_U32 },
1891 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1892 { .type = NLA_UNSPEC },
1893 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1894 { .type = NLA_S32 },
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1896 { .type = NLA_S32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1898 { .type = NLA_U32 },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1900 { .type = NLA_U32 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1902 { .type = NLA_U32 },
1903 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1904 = { .type = NLA_U32 },
1905 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1906 { .type = NLA_U32 },
1907 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1908 NLA_U32 },
1909};
1910
1911static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1912{
1913 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1914 struct sk_buff *skb = NULL;
1915 tpSirEXTScanCapabilitiesEvent pData =
1916 (tpSirEXTScanCapabilitiesEvent) pMsg;
1917
1918 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1920 "or pData(%p) is null"), pData);
1921 return;
1922 }
1923
1924 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1925 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1926 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1927 GFP_KERNEL);
1928
1929 if (!skb) {
1930 hddLog(VOS_TRACE_LEVEL_ERROR,
1931 FL("cfg80211_vendor_event_alloc failed"));
1932 return;
1933 }
1934
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1939 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1940 pData->maxRssiSampleSize);
1941 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1942 pData->maxScanReportingThreshold);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1944 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1945 pData->maxSignificantWifiChangeAPs);
1946 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1947 pData->maxBsidHistoryEntries);
1948
1949 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1950 pData->requestId) ||
1951 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1952 nla_put_u32(skb,
1953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1954 pData->scanCacheSize) ||
1955 nla_put_u32(skb,
1956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1957 pData->scanBuckets) ||
1958 nla_put_u32(skb,
1959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1960 pData->maxApPerScan) ||
1961 nla_put_u32(skb,
1962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1963 pData->maxRssiSampleSize) ||
1964 nla_put_u32(skb,
1965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1966 pData->maxScanReportingThreshold) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1969 pData->maxHotlistAPs) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1972 pData->maxSignificantWifiChangeAPs) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1975 pData->maxBsidHistoryEntries)) {
1976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1977 goto nla_put_failure;
1978 }
1979
1980 cfg80211_vendor_event(skb, GFP_KERNEL);
1981 return;
1982
1983nla_put_failure:
1984 kfree_skb(skb);
1985 return;
1986}
1987
1988
1989static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1990{
1991 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1992 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1993 struct sk_buff *skb = NULL;
1994 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1995
1996
1997 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1999 "or pData(%p) is null"), pData);
2000 return;
2001 }
2002
2003 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2004 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2005 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2006 GFP_KERNEL);
2007
2008 if (!skb) {
2009 hddLog(VOS_TRACE_LEVEL_ERROR,
2010 FL("cfg80211_vendor_event_alloc failed"));
2011 return;
2012 }
2013 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2015 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2016
2017 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2018 pData->requestId) ||
2019 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2021 goto nla_put_failure;
2022 }
2023
2024 /*
2025 * Store the Request ID for comparing with the requestID obtained
2026 * in other requests.HDD shall return a failure is the extscan_stop
2027 * request is issued with a different requestId as that of the
2028 * extscan_start request. Also, This requestId shall be used while
2029 * indicating the full scan results to the upper layers.
2030 * The requestId is stored with the assumption that the firmware
2031 * shall return the ext scan start request's requestId in ext scan
2032 * start response.
2033 */
2034 if (pData->status == 0)
2035 pMac->sme.extScanStartReqId = pData->requestId;
2036
2037
2038 cfg80211_vendor_event(skb, GFP_KERNEL);
2039 return;
2040
2041nla_put_failure:
2042 kfree_skb(skb);
2043 return;
2044}
2045
2046
2047static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2048{
2049 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2050 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2051 struct sk_buff *skb = NULL;
2052
2053 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2055 "or pData(%p) is null"), pData);
2056 return;
2057 }
2058
2059 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2060 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2061 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2062 GFP_KERNEL);
2063
2064 if (!skb) {
2065 hddLog(VOS_TRACE_LEVEL_ERROR,
2066 FL("cfg80211_vendor_event_alloc failed"));
2067 return;
2068 }
2069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2070 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2071
2072 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2073 pData->requestId) ||
2074 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2076 goto nla_put_failure;
2077 }
2078
2079 cfg80211_vendor_event(skb, GFP_KERNEL);
2080 return;
2081
2082nla_put_failure:
2083 kfree_skb(skb);
2084 return;
2085}
2086
2087
2088static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2089 void *pMsg)
2090{
2091 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2092 struct sk_buff *skb = NULL;
2093 tpSirEXTScanSetBssidHotListRspParams pData =
2094 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2095
2096 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2098 "or pData(%p) is null"), pData);
2099 return;
2100 }
2101 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2102 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2103 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2104 GFP_KERNEL);
2105
2106 if (!skb) {
2107 hddLog(VOS_TRACE_LEVEL_ERROR,
2108 FL("cfg80211_vendor_event_alloc failed"));
2109 return;
2110 }
2111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2113 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2114
2115 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2116 pData->requestId) ||
2117 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2119 goto nla_put_failure;
2120 }
2121
2122 cfg80211_vendor_event(skb, GFP_KERNEL);
2123 return;
2124
2125nla_put_failure:
2126 kfree_skb(skb);
2127 return;
2128}
2129
2130static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2131 void *pMsg)
2132{
2133 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2134 struct sk_buff *skb = NULL;
2135 tpSirEXTScanResetBssidHotlistRspParams pData =
2136 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2137
2138 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2140 "or pData(%p) is null"), pData);
2141 return;
2142 }
2143
2144 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2145 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2146 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2147 GFP_KERNEL);
2148
2149 if (!skb) {
2150 hddLog(VOS_TRACE_LEVEL_ERROR,
2151 FL("cfg80211_vendor_event_alloc failed"));
2152 return;
2153 }
2154 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2155 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2156
2157 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2158 pData->requestId) ||
2159 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2161 goto nla_put_failure;
2162 }
2163
2164 cfg80211_vendor_event(skb, GFP_KERNEL);
2165 return;
2166
2167nla_put_failure:
2168 kfree_skb(skb);
2169 return;
2170}
2171
2172
2173static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2174 void *pMsg)
2175{
2176 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2177 struct sk_buff *skb = NULL;
2178 tpSirEXTScanSetSignificantChangeRspParams pData =
2179 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2180
2181 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2183 "or pData(%p) is null"), pData);
2184 return;
2185 }
2186
2187 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2188 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2189 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2190 GFP_KERNEL);
2191
2192 if (!skb) {
2193 hddLog(VOS_TRACE_LEVEL_ERROR,
2194 FL("cfg80211_vendor_event_alloc failed"));
2195 return;
2196 }
2197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2199 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2200
2201 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2202 pData->requestId) ||
2203 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2205 goto nla_put_failure;
2206 }
2207
2208 cfg80211_vendor_event(skb, GFP_KERNEL);
2209 return;
2210
2211nla_put_failure:
2212 kfree_skb(skb);
2213 return;
2214}
2215
2216
2217static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2218 void *pMsg)
2219{
2220 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2221 struct sk_buff *skb = NULL;
2222 tpSirEXTScanResetSignificantChangeRspParams pData =
2223 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2224
2225 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2227 "or pData(%p) is null"), pData);
2228 return;
2229 }
2230
2231 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2232 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2233 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2234 GFP_KERNEL);
2235
2236 if (!skb) {
2237 hddLog(VOS_TRACE_LEVEL_ERROR,
2238 FL("cfg80211_vendor_event_alloc failed"));
2239 return;
2240 }
2241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2243 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2244
2245 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2246 pData->requestId) ||
2247 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2249 goto nla_put_failure;
2250 }
2251
2252 cfg80211_vendor_event(skb, GFP_KERNEL);
2253 return;
2254
2255nla_put_failure:
2256 kfree_skb(skb);
2257 return;
2258}
2259
2260static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2261 void *pMsg)
2262{
2263 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2264 struct sk_buff *skb = NULL;
2265 tANI_U32 i = 0, j, resultsPerEvent;
2266 tANI_S32 totalResults;
2267 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2268 tpSirWifiScanResult pSirWifiScanResult;
2269
2270 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2272 "or pData(%p) is null"), pData);
2273 return;
2274 }
2275 totalResults = pData->numOfAps;
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2278 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2279
2280 do{
2281 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2282 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2283 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2284
2285 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2286 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2287 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2288 GFP_KERNEL);
2289
2290 if (!skb) {
2291 hddLog(VOS_TRACE_LEVEL_ERROR,
2292 FL("cfg80211_vendor_event_alloc failed"));
2293 return;
2294 }
2295
2296 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2297
2298 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2299 pData->requestId) ||
2300 nla_put_u32(skb,
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2302 resultsPerEvent)) {
2303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2304 goto fail;
2305 }
2306 if (nla_put_u8(skb,
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2308 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2309 {
2310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2311 goto fail;
2312 }
2313
2314 if (resultsPerEvent) {
2315 struct nlattr *aps;
2316
2317 aps = nla_nest_start(skb,
2318 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2319 if (!aps)
2320 {
2321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2322 goto fail;
2323 }
2324
2325 for (j = 0; j < resultsPerEvent; j++, i++) {
2326 struct nlattr *ap;
2327 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2328 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2329
2330 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2331 "Ssid (%s)"
2332 "Bssid: %pM "
2333 "Channel (%u)"
2334 "Rssi (%d)"
2335 "RTT (%u)"
2336 "RTT_SD (%u)",
2337 i,
2338 pSirWifiScanResult->ts,
2339 pSirWifiScanResult->ssid,
2340 pSirWifiScanResult->bssid,
2341 pSirWifiScanResult->channel,
2342 pSirWifiScanResult->rssi,
2343 pSirWifiScanResult->rtt,
2344 pSirWifiScanResult->rtt_sd);
2345
2346 ap = nla_nest_start(skb, j + 1);
2347 if (!ap)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2350 goto fail;
2351 }
2352
2353 if (nla_put_u64(skb,
2354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2355 pSirWifiScanResult->ts) )
2356 {
2357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2358 goto fail;
2359 }
2360 if (nla_put(skb,
2361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2362 sizeof(pSirWifiScanResult->ssid),
2363 pSirWifiScanResult->ssid) )
2364 {
2365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2366 goto fail;
2367 }
2368 if (nla_put(skb,
2369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2370 sizeof(pSirWifiScanResult->bssid),
2371 pSirWifiScanResult->bssid) )
2372 {
2373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2374 goto fail;
2375 }
2376 if (nla_put_u32(skb,
2377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2378 pSirWifiScanResult->channel) )
2379 {
2380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2381 goto fail;
2382 }
2383 if (nla_put_u32(skb,
2384 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2385 pSirWifiScanResult->rssi) )
2386 {
2387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2388 goto fail;
2389 }
2390 if (nla_put_u32(skb,
2391 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2392 pSirWifiScanResult->rtt) )
2393 {
2394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2395 goto fail;
2396 }
2397 if (nla_put_u32(skb,
2398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2399 pSirWifiScanResult->rtt_sd))
2400 {
2401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2402 goto fail;
2403 }
2404
2405 nla_nest_end(skb, ap);
2406 }
2407 nla_nest_end(skb, aps);
2408
2409 }
2410 cfg80211_vendor_event(skb, GFP_KERNEL);
2411 } while (totalResults > 0);
2412
2413 return;
2414fail:
2415 kfree_skb(skb);
2416 return;
2417}
2418
2419static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2420 void *pMsg)
2421{
2422 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tANI_U32 i;
2426
2427 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2429 "or pData(%p) is null"), pData);
2430 return;
2431 }
2432
2433 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2434 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2435 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2436 GFP_KERNEL);
2437
2438 if (!skb) {
2439 hddLog(VOS_TRACE_LEVEL_ERROR,
2440 FL("cfg80211_vendor_event_alloc failed"));
2441 return;
2442 }
2443 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2446 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2447
2448 for (i = 0; i < pData->numOfAps; i++) {
2449 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2450 "Ssid (%s) "
2451 "Bssid (" MAC_ADDRESS_STR ") "
2452 "Channel (%u) "
2453 "Rssi (%d) "
2454 "RTT (%u) "
2455 "RTT_SD (%u) ",
2456 i,
2457 pData->ap[i].ts,
2458 pData->ap[i].ssid,
2459 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2460 pData->ap[i].channel,
2461 pData->ap[i].rssi,
2462 pData->ap[i].rtt,
2463 pData->ap[i].rtt_sd);
2464 }
2465
2466 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2467 pData->requestId) ||
2468 nla_put_u32(skb,
2469 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2470 pData->numOfAps)) {
2471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2472 goto fail;
2473 }
2474 if (pData->numOfAps) {
2475 struct nlattr *aps;
2476
2477 aps = nla_nest_start(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2479 if (!aps)
2480 goto fail;
2481
2482 for (i = 0; i < pData->numOfAps; i++) {
2483 struct nlattr *ap;
2484
2485 ap = nla_nest_start(skb, i + 1);
2486 if (!ap)
2487 goto fail;
2488
2489 if (nla_put_u64(skb,
2490 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2491 pData->ap[i].ts) ||
2492 nla_put(skb,
2493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2494 sizeof(pData->ap[i].ssid),
2495 pData->ap[i].ssid) ||
2496 nla_put(skb,
2497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2498 sizeof(pData->ap[i].bssid),
2499 pData->ap[i].bssid) ||
2500 nla_put_u32(skb,
2501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2502 pData->ap[i].channel) ||
2503 nla_put_s32(skb,
2504 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2505 pData->ap[i].rssi) ||
2506 nla_put_u32(skb,
2507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2508 pData->ap[i].rtt) ||
2509 nla_put_u32(skb,
2510 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2511 pData->ap[i].rtt_sd))
2512 goto fail;
2513
2514 nla_nest_end(skb, ap);
2515 }
2516 nla_nest_end(skb, aps);
2517
2518 if (nla_put_u8(skb,
2519 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2520 pData->moreData))
2521 goto fail;
2522 }
2523
2524 cfg80211_vendor_event(skb, GFP_KERNEL);
2525 return;
2526
2527fail:
2528 kfree_skb(skb);
2529 return;
2530
2531}
2532static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2533 void *pMsg)
2534{
2535 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2536 struct sk_buff *skb = NULL;
2537 tANI_U32 i, j;
2538 tpSirWifiSignificantChangeEvent pData =
2539 (tpSirWifiSignificantChangeEvent) pMsg;
2540
2541 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2543 "or pData(%p) is null"), pData);
2544 return;
2545 }
2546 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2547 EXTSCAN_EVENT_BUF_SIZE,
2548 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2549 GFP_KERNEL);
2550
2551 if (!skb) {
2552 hddLog(VOS_TRACE_LEVEL_ERROR,
2553 FL("cfg80211_vendor_event_alloc failed"));
2554 return;
2555 }
2556 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2557 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2558 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2559 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2560 pData->numSigRssiBss);
2561 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2562
2563 for (i = 0; i < pData->numSigRssiBss; i++) {
2564 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2565 " num RSSI %u ",
2566 i, pData->sigRssiResult[i].bssid,
2567 pData->sigRssiResult[i].channel,
2568 pData->sigRssiResult[i].numRssi);
2569
2570 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2571
2572 hddLog(VOS_TRACE_LEVEL_INFO,
2573 " [%d]",
2574 pData->sigRssiResult[i].rssi[0]);
2575
2576 }
2577 }
2578
2579
2580 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2581 pData->requestId) ||
2582 nla_put_u32(skb,
2583 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2584 pData->numSigRssiBss)) {
2585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2586 goto fail;
2587 }
2588
2589 if (pData->numSigRssiBss) {
2590 struct nlattr *aps;
2591 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2592 if (!aps)
2593 goto fail;
2594 for (i = 0; i < pData->numSigRssiBss; i++) {
2595 struct nlattr *ap;
2596
2597 ap = nla_nest_start(skb, i);
2598 if (!ap)
2599 goto fail;
2600 if (nla_put(skb,
2601 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2602 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2603 nla_put_u32(skb,
2604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2605 pData->sigRssiResult[i].channel) ||
2606 nla_put_u32(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2608 pData->sigRssiResult[i].numRssi) ||
2609 nla_put(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2611 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2612 pData->sigRssiResult[i].rssi))
2613 goto fail;
2614 nla_nest_end(skb, ap);
2615 }
2616 nla_nest_end(skb, aps);
2617 if (nla_put_u8(skb,
2618 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2619 pData->moreData))
2620 goto fail;
2621 }
2622 cfg80211_vendor_event(skb, GFP_KERNEL);
2623 return;
2624fail:
2625 kfree_skb(skb);
2626 return;
2627}
2628
2629static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2630 void *pMsg)
2631{
2632 struct sk_buff *skb;
2633 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2634 tpSirWifiFullScanResultEvent pData =
2635 (tpSirWifiFullScanResultEvent) (pMsg);
2636
2637 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2639 "or pData(%p) is null"), pData);
2640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2644 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2645 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2646 GFP_KERNEL);
2647
2648 if (!skb) {
2649 hddLog(VOS_TRACE_LEVEL_ERROR,
2650 FL("cfg80211_vendor_event_alloc failed"));
2651 return;
2652 }
2653
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2657 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2658 "Ssid (%s)"
2659 "Bssid (" MAC_ADDRESS_STR ")"
2660 "Channel (%u)"
2661 "Rssi (%d)"
2662 "RTT (%u)"
2663 "RTT_SD (%u)"),
2664 pData->ap.ts,
2665 pData->ap.ssid,
2666 MAC_ADDR_ARRAY(pData->ap.bssid),
2667 pData->ap.channel,
2668 pData->ap.rssi,
2669 pData->ap.rtt,
2670 pData->ap.rtt_sd);
2671 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2672 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2673 pData->requestId) ||
2674 nla_put_u64(skb,
2675 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2676 pData->ap.ts) ||
2677 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2678 sizeof(pData->ap.ssid),
2679 pData->ap.ssid) ||
2680 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2681 WNI_CFG_BSSID_LEN,
2682 pData->ap.bssid) ||
2683 nla_put_u32(skb,
2684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2685 pData->ap.channel) ||
2686 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2687 pData->ap.rssi) ||
2688 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2689 pData->ap.rtt) ||
2690 nla_put_u32(skb,
2691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2692 pData->ap.rtt_sd) ||
2693 nla_put_u16(skb,
2694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2695 pData->ap.beaconPeriod) ||
2696 nla_put_u16(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2698 pData->ap.capability) ||
2699 nla_put_u32(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2701 pData->ieLength))
2702 {
2703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2704 goto nla_put_failure;
2705 }
2706 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2707 pData->ieLength,
2708 pData->ie))
2709 {
2710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2711 goto nla_put_failure;
2712 }
2713
2714 cfg80211_vendor_event(skb, GFP_KERNEL);
2715 return;
2716
2717nla_put_failure:
2718 kfree_skb(skb);
2719 return;
2720}
2721
2722static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2723 void *pMsg)
2724{
2725 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2726 struct sk_buff *skb = NULL;
2727 tpSirEXTScanResultsAvailableIndParams pData =
2728 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2729
2730 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2732 "or pData(%p) is null"), pData);
2733 return;
2734 }
2735
2736 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2737 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2738 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2739 GFP_KERNEL);
2740
2741 if (!skb) {
2742 hddLog(VOS_TRACE_LEVEL_ERROR,
2743 FL("cfg80211_vendor_event_alloc failed"));
2744 return;
2745 }
2746
2747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2749 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2750 pData->numResultsAvailable);
2751 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2752 pData->requestId) ||
2753 nla_put_u32(skb,
2754 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2755 pData->numResultsAvailable)) {
2756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2757 goto nla_put_failure;
2758 }
2759
2760 cfg80211_vendor_event(skb, GFP_KERNEL);
2761 return;
2762
2763nla_put_failure:
2764 kfree_skb(skb);
2765 return;
2766}
2767
2768static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2769{
2770 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2771 struct sk_buff *skb = NULL;
2772 tpSirEXTScanProgressIndParams pData =
2773 (tpSirEXTScanProgressIndParams) pMsg;
2774
2775 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2777 "or pData(%p) is null"), pData);
2778 return;
2779 }
2780
2781 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2782 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2783 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2784 GFP_KERNEL);
2785
2786 if (!skb) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR,
2788 FL("cfg80211_vendor_event_alloc failed"));
2789 return;
2790 }
2791 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2792 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2793 pData->extScanEventType);
2794 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2795 pData->status);
2796
2797 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2798 pData->extScanEventType) ||
2799 nla_put_u32(skb,
2800 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2801 pData->status)) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2803 goto nla_put_failure;
2804 }
2805
2806 cfg80211_vendor_event(skb, GFP_KERNEL);
2807 return;
2808
2809nla_put_failure:
2810 kfree_skb(skb);
2811 return;
2812}
2813
2814void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2815 void *pMsg)
2816{
2817 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2818
2819 if (wlan_hdd_validate_context(pHddCtx)) {
2820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2821 return;
2822 }
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2825
2826
2827 switch(evType) {
2828 case SIR_HAL_EXTSCAN_START_RSP:
2829 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2830 break;
2831
2832 case SIR_HAL_EXTSCAN_STOP_RSP:
2833 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2834 break;
2835 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2836 /* There is no need to send this response to upper layer
2837 Just log the message */
2838 hddLog(VOS_TRACE_LEVEL_INFO,
2839 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2840 break;
2841 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2842 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2843 break;
2844
2845 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2846 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2847 break;
2848
2849 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2850 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2851 break;
2852
2853 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2854 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2855 break;
2856 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2857 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2858 break;
2859 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2860 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2861 break;
2862 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2863 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2864 break;
2865 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2866 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2867 break;
2868 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2869 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2870 break;
2871 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2872 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2875 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2876 break;
2877 default:
2878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2879 break;
2880 }
2881}
2882
2883static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2884 struct wireless_dev *wdev,
2885 void *data, int dataLen)
2886{
2887 tpSirGetEXTScanCapabilitiesReqParams pReqMsg = NULL;
2888 struct net_device *dev = wdev->netdev;
2889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2890 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2891 struct nlattr
2892 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2893 eHalStatus status;
2894
2895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2896 status = wlan_hdd_validate_context(pHddCtx);
2897 if (0 != status)
2898 {
2899 hddLog(VOS_TRACE_LEVEL_ERROR,
2900 FL("HDD context is not valid"));
2901 return -EINVAL;
2902 }
2903 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2904 data, dataLen,
2905 wlan_hdd_extscan_config_policy)) {
2906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2907 return -EINVAL;
2908 }
2909
2910 /* Parse and fetch request Id */
2911 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2913 return -EINVAL;
2914 }
2915
2916 pReqMsg = (tpSirGetEXTScanCapabilitiesReqParams)
2917 vos_mem_malloc(sizeof(*pReqMsg));
2918 if (!pReqMsg) {
2919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2920 return -ENOMEM;
2921 }
2922
2923 pReqMsg->requestId = nla_get_u32(
2924 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2925 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2926
2927 pReqMsg->sessionId = pAdapter->sessionId;
2928 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2929
2930 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, pReqMsg);
2931 if (!HAL_STATUS_SUCCESS(status)) {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
2934 vos_mem_free(pReqMsg);
2935 return -EINVAL;
2936 }
2937
2938 return 0;
2939}
2940
2941
2942static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2943 struct wireless_dev *wdev,
2944 void *data, int dataLen)
2945{
2946 tpSirEXTScanGetCachedResultsReqParams pReqMsg = NULL;
2947 struct net_device *dev = wdev->netdev;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2950 struct nlattr
2951 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2952 eHalStatus status;
2953
2954 status = wlan_hdd_validate_context(pHddCtx);
2955 if (0 != status)
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR,
2958 FL("HDD context is not valid"));
2959 return -EINVAL;
2960 }
2961 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2962 data, dataLen,
2963 wlan_hdd_extscan_config_policy)) {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2965 return -EINVAL;
2966 }
2967 /* Parse and fetch request Id */
2968 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2970 return -EINVAL;
2971 }
2972 pReqMsg = (tpSirEXTScanGetCachedResultsReqParams)
2973 vos_mem_malloc(sizeof(*pReqMsg));
2974 if (!pReqMsg) {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2976 return -ENOMEM;
2977 }
2978
2979 pReqMsg->requestId = nla_get_u32(
2980 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2981
2982 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
2983
2984 pReqMsg->sessionId = pAdapter->sessionId;
2985 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
2986
2987 /* Parse and fetch flush parameter */
2988 if (!tb
2989 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2990 {
2991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2992 goto failed;
2993 }
2994 pReqMsg->flush = nla_get_u8(
2995 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
2996
2997 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), pReqMsg->flush);
2998
2999 status = sme_getCachedResults(pHddCtx->hHal, pReqMsg);
3000 if (!HAL_STATUS_SUCCESS(status)) {
3001 hddLog(VOS_TRACE_LEVEL_ERROR,
3002 FL("sme_getCachedResults failed(err=%d)"), status);
3003 vos_mem_free(pReqMsg);
3004 return -EINVAL;
3005 }
3006 return 0;
3007
3008failed:
3009 vos_mem_free(pReqMsg);
3010 return -EINVAL;
3011}
3012
3013static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3014 struct wireless_dev *wdev,
3015 void *data, int dataLen)
3016{
3017 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3018 struct net_device *dev = wdev->netdev;
3019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3020 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3021 struct nlattr
3022 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3023 struct nlattr
3024 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3025 struct nlattr *apTh;
3026 eHalStatus status;
3027 tANI_U8 i = 0;
3028 int rem;
3029
3030 status = wlan_hdd_validate_context(pHddCtx);
3031 if (0 != status)
3032 {
3033 hddLog(VOS_TRACE_LEVEL_ERROR,
3034 FL("HDD context is not valid"));
3035 return -EINVAL;
3036 }
3037 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3038 data, dataLen,
3039 wlan_hdd_extscan_config_policy)) {
3040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3041 return -EINVAL;
3042 }
3043
3044 /* Parse and fetch request Id */
3045 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3047 return -EINVAL;
3048 }
3049
3050 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3051 vos_mem_malloc(sizeof(*pReqMsg));
3052 if (!pReqMsg) {
3053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3054 return -ENOMEM;
3055 }
3056
3057 pReqMsg->requestId = nla_get_u32(
3058 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3060
3061 /* Parse and fetch number of APs */
3062 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3064 goto fail;
3065 }
3066
3067 pReqMsg->sessionId = pAdapter->sessionId;
3068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3069
3070 pReqMsg->numAp = nla_get_u32(
3071 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3072 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3073
3074 nla_for_each_nested(apTh,
3075 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3076 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3077 nla_data(apTh), nla_len(apTh),
3078 NULL)) {
3079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3080 goto fail;
3081 }
3082
3083 /* Parse and fetch MAC address */
3084 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3086 goto fail;
3087 }
3088 memcpy(pReqMsg->ap[i].bssid, nla_data(
3089 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3090 sizeof(tSirMacAddr));
3091 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3092
3093 /* Parse and fetch low RSSI */
3094 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3096 goto fail;
3097 }
3098 pReqMsg->ap[i].low = nla_get_s32(
3099 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3100 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3101
3102 /* Parse and fetch high RSSI */
3103 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3105 goto fail;
3106 }
3107 pReqMsg->ap[i].high = nla_get_s32(
3108 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3109 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3110 pReqMsg->ap[i].high);
3111
3112 /* Parse and fetch channel */
3113 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3115 goto fail;
3116 }
3117 pReqMsg->ap[i].channel = nla_get_u32(
3118 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3119 hddLog(VOS_TRACE_LEVEL_INFO,
3120 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3121 i++;
3122 }
3123 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3124 if (!HAL_STATUS_SUCCESS(status)) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR,
3126 FL("sme_SetBssHotlist failed(err=%d)"), status);
3127 vos_mem_free(pReqMsg);
3128 return -EINVAL;
3129 }
3130
3131 return 0;
3132
3133fail:
3134 vos_mem_free(pReqMsg);
3135 return -EINVAL;
3136}
3137
3138static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3139 struct wireless_dev *wdev,
3140 void *data, int dataLen)
3141{
3142 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3143 struct net_device *dev = wdev->netdev;
3144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3145 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3146 struct nlattr
3147 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3148 struct nlattr
3149 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3150 struct nlattr *apTh;
3151 eHalStatus status;
3152 int i = 0;
3153 int rem;
3154
3155 status = wlan_hdd_validate_context(pHddCtx);
3156 if (0 != status)
3157 {
3158 hddLog(VOS_TRACE_LEVEL_ERROR,
3159 FL("HDD context is not valid"));
3160 return -EINVAL;
3161 }
3162 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3163 data, dataLen,
3164 wlan_hdd_extscan_config_policy)) {
3165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3166 return -EINVAL;
3167 }
3168
3169 /* Parse and fetch request Id */
3170 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3172 return -EINVAL;
3173 }
3174
3175 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
3176 vos_mem_malloc(sizeof(*pReqMsg));
3177 if (!pReqMsg) {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3179 return -ENOMEM;
3180 }
3181
3182 pReqMsg->requestId = nla_get_u32(
3183 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3185
3186 /* Parse and fetch RSSI sample size */
3187 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3188 {
3189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3190 goto fail;
3191 }
3192 pReqMsg->rssiSampleSize = nla_get_u32(
3193 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3194 hddLog(VOS_TRACE_LEVEL_INFO,
3195 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3196
3197 /* Parse and fetch lost AP sample size */
3198 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3199 {
3200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3201 goto fail;
3202 }
3203 pReqMsg->lostApSampleSize = nla_get_u32(
3204 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3205 hddLog(VOS_TRACE_LEVEL_INFO,
3206 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3207 /* Parse and fetch minimum Breaching */
3208 if (!tb
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3211 goto fail;
3212 }
3213 pReqMsg->minBreaching = nla_get_u32(
3214 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3215 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3216
3217 /* Parse and fetch number of APs */
3218 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3220 goto fail;
3221 }
3222 pReqMsg->numAp = nla_get_u32(
3223 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3225
3226 pReqMsg->sessionId = pAdapter->sessionId;
3227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3228
3229 nla_for_each_nested(apTh,
3230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3231 if(nla_parse(tb2,
3232 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3233 nla_data(apTh), nla_len(apTh),
3234 NULL)) {
3235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3236 goto fail;
3237 }
3238
3239 /* Parse and fetch MAC address */
3240 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3242 goto fail;
3243 }
3244 memcpy(pReqMsg->ap[i].bssid, nla_data(
3245 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3246 sizeof(tSirMacAddr));
3247
3248 /* Parse and fetch low RSSI */
3249 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3251 goto fail;
3252 }
3253 pReqMsg->ap[i].low = nla_get_s32(
3254 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3255 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3256
3257 /* Parse and fetch high RSSI */
3258 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3260 goto fail;
3261 }
3262 pReqMsg->ap[i].high = nla_get_s32(
3263 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3264 hddLog(VOS_TRACE_LEVEL_INFO,
3265 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3266
3267 /* Parse and fetch channel */
3268 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3270 goto fail;
3271 }
3272 pReqMsg->ap[i].channel = nla_get_u32(
3273 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3274 hddLog(VOS_TRACE_LEVEL_INFO,
3275 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3276 i++;
3277 }
3278
3279 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3280 if (!HAL_STATUS_SUCCESS(status)) {
3281 hddLog(VOS_TRACE_LEVEL_ERROR,
3282 FL("sme_SetSignificantChange failed(err=%d)"), status);
3283 vos_mem_free(pReqMsg);
3284 return -EINVAL;
3285 }
3286
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3288 return 0;
3289
3290fail:
3291 vos_mem_free(pReqMsg);
3292 return -EINVAL;
3293}
3294
3295static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3296 struct wireless_dev *wdev,
3297 void *data, int dataLen)
3298{
3299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3300 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3301 tANI_U8 numChannels = 0;
3302 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3303 tANI_U32 requestId;
3304 tWifiBand wifiBand;
3305 eHalStatus status;
3306 struct sk_buff *replySkb;
3307 tANI_U8 i;
3308
3309 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3310 status = wlan_hdd_validate_context(pHddCtx);
3311 if (0 != status)
3312 {
3313 hddLog(VOS_TRACE_LEVEL_ERROR,
3314 FL("HDD context is not valid"));
3315 return -EINVAL;
3316 }
3317 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3318 data, dataLen,
3319 wlan_hdd_extscan_config_policy)) {
3320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3321 return -EINVAL;
3322 }
3323
3324 /* Parse and fetch request Id */
3325 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3327 return -EINVAL;
3328 }
3329 requestId = nla_get_u32(
3330 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3332
3333 /* Parse and fetch wifi band */
3334 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3335 {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3337 return -EINVAL;
3338 }
3339 wifiBand = nla_get_u32(
3340 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3342
3343 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3344 wifiBand, ChannelList,
3345 &numChannels);
3346 if (eHAL_STATUS_SUCCESS != status) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3349 return -EINVAL;
3350 }
3351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3352 for (i = 0; i < numChannels; i++)
3353 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3354
3355 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3356 sizeof(u32) * numChannels +
3357 NLMSG_HDRLEN);
3358
3359 if (!replySkb) {
3360 hddLog(VOS_TRACE_LEVEL_ERROR,
3361 FL("valid channels: buffer alloc fail"));
3362 return -EINVAL;
3363 }
3364 if (nla_put_u32(replySkb,
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3366 numChannels) ||
3367 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3368 sizeof(u32) * numChannels, ChannelList)) {
3369
3370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3371 kfree_skb(replySkb);
3372 return -EINVAL;
3373 }
3374
3375 return cfg80211_vendor_cmd_reply(replySkb);
3376}
3377
3378static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3379 struct wireless_dev *wdev,
3380 void *data, int dataLen)
3381{
3382 tpSirEXTScanStartReqParams pReqMsg = NULL;
3383 struct net_device *dev = wdev->netdev;
3384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3386 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3387 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3388 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3389 struct nlattr *buckets;
3390 struct nlattr *channels;
3391 int rem1;
3392 int rem2;
3393 eHalStatus status;
3394 tANI_U8 bktIndex;
3395 tANI_U32 i = 0, j = 0;
3396
3397 status = wlan_hdd_validate_context(pHddCtx);
3398 if (0 != status)
3399 {
3400 hddLog(VOS_TRACE_LEVEL_ERROR,
3401 FL("HDD context is not valid"));
3402 return -EINVAL;
3403 }
3404 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3405 data, dataLen,
3406 wlan_hdd_extscan_config_policy)) {
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3408 return -EINVAL;
3409 }
3410
3411 /* Parse and fetch request Id */
3412 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3414 return -EINVAL;
3415 }
3416
3417 pReqMsg = (tpSirEXTScanStartReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3418 if (!pReqMsg) {
3419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3420 return -ENOMEM;
3421 }
3422
3423 pReqMsg->requestId = nla_get_u32(
3424 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3425 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3426
3427 pReqMsg->sessionId = pAdapter->sessionId;
3428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3429
3430 /* Parse and fetch base period */
3431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3433 goto fail;
3434 }
3435 pReqMsg->basePeriod = nla_get_u32(
3436 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3437 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3438 pReqMsg->basePeriod);
3439
3440 /* Parse and fetch max AP per scan */
3441 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3443 goto fail;
3444 }
3445 pReqMsg->maxAPperScan = nla_get_u32(
3446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3448 pReqMsg->maxAPperScan);
3449
3450 /* Parse and fetch report threshold */
3451 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3453 goto fail;
3454 }
3455 pReqMsg->reportThreshold = nla_get_u8(
3456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3458 pReqMsg->reportThreshold);
3459
3460 /* Parse and fetch number of buckets */
3461 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3463 goto fail;
3464 }
3465 pReqMsg->numBuckets = nla_get_u8(
3466 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3467 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3468 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3469 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3470 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3471 }
3472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3473 pReqMsg->numBuckets);
3474 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3476 goto fail;
3477 }
3478
3479 nla_for_each_nested(buckets,
3480 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3481 if(nla_parse(bucket,
3482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3483 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3485 goto fail;
3486 }
3487
3488 /* Parse and fetch bucket spec */
3489 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3490 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3491 goto fail;
3492 }
3493 bktIndex = nla_get_u8(
3494 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3496 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3497
3498 /* Parse and fetch wifi band */
3499 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3501 goto fail;
3502 }
3503 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3504 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3506 pReqMsg->buckets[bktIndex].band);
3507
3508 /* Parse and fetch period */
3509 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3511 goto fail;
3512 }
3513 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3514 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3515 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3516 pReqMsg->buckets[bktIndex].period);
3517
3518 /* Parse and fetch report events */
3519 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3521 goto fail;
3522 }
3523 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3524 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3525 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3526 pReqMsg->buckets[bktIndex].reportEvents);
3527
3528 /* Parse and fetch number of channels */
3529 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3531 goto fail;
3532 }
3533 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3534 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3535 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3536 pReqMsg->buckets[bktIndex].numChannels);
3537
3538 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3540 goto fail;
3541 }
3542
3543 j = 0;
3544 nla_for_each_nested(channels,
3545 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3546 if(nla_parse(channel,
3547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3548 nla_data(channels), nla_len(channels),
3549 NULL)) { //wlan_hdd_extscan_config_policy here
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3551 goto fail;
3552 }
3553
3554 /* Parse and fetch channel */
3555 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3557 goto fail;
3558 }
3559 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3560 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3561 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3562 pReqMsg->buckets[bktIndex].channels[j].channel);
3563
3564 /* Parse and fetch dwell time */
3565 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3567 goto fail;
3568 }
3569 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3570 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3572 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3573
3574 /* Parse and fetch channel spec passive */
3575 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3576 hddLog(VOS_TRACE_LEVEL_ERROR,
3577 FL("attr channel spec passive failed"));
3578 goto fail;
3579 }
3580 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3581 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3582 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3583 pReqMsg->buckets[bktIndex].channels[j].passive);
3584 j++;
3585 }
3586 i++;
3587 }
3588 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3589 if (!HAL_STATUS_SUCCESS(status)) {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("sme_EXTScanStart failed(err=%d)"), status);
3592 vos_mem_free(pReqMsg);
3593 return -EINVAL;
3594 }
3595
3596 return 0;
3597
3598fail:
3599 vos_mem_free(pReqMsg);
3600 return -EINVAL;
3601}
3602
3603static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3604 struct wireless_dev *wdev,
3605 void *data, int dataLen)
3606{
3607 tpSirEXTScanStopReqParams pReqMsg = NULL;
3608 struct net_device *dev = wdev->netdev;
3609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3610 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3611 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3612 eHalStatus status;
3613
3614 status = wlan_hdd_validate_context(pHddCtx);
3615 if (0 != status)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR,
3618 FL("HDD context is not valid"));
3619 return -EINVAL;
3620 }
3621 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3622 data, dataLen,
3623 wlan_hdd_extscan_config_policy)) {
3624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3625 return -EINVAL;
3626 }
3627
3628 /* Parse and fetch request Id */
3629 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3631 return -EINVAL;
3632 }
3633
3634 pReqMsg = (tpSirEXTScanStopReqParams) vos_mem_malloc(sizeof(*pReqMsg));
3635 if (!pReqMsg) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3637 return -ENOMEM;
3638 }
3639
3640 pReqMsg->requestId = nla_get_u32(
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3643
3644 pReqMsg->sessionId = pAdapter->sessionId;
3645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3646
3647 status = sme_EXTScanStop(pHddCtx->hHal, pReqMsg);
3648 if (!HAL_STATUS_SUCCESS(status)) {
3649 hddLog(VOS_TRACE_LEVEL_ERROR,
3650 FL("sme_EXTScanStop failed(err=%d)"), status);
3651 vos_mem_free(pReqMsg);
3652 return -EINVAL;
3653 }
3654
3655 return 0;
3656}
3657
3658static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3659 struct wireless_dev *wdev,
3660 void *data, int dataLen)
3661{
3662 tpSirEXTScanResetBssidHotlistReqParams pReqMsg = NULL;
3663 struct net_device *dev = wdev->netdev;
3664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3665 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3666 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3667 eHalStatus status;
3668
3669 status = wlan_hdd_validate_context(pHddCtx);
3670 if (0 != status)
3671 {
3672 hddLog(VOS_TRACE_LEVEL_ERROR,
3673 FL("HDD context is not valid"));
3674 return -EINVAL;
3675 }
3676 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3677 data, dataLen,
3678 wlan_hdd_extscan_config_policy)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3680 return -EINVAL;
3681 }
3682
3683 /* Parse and fetch request Id */
3684 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3686 return -EINVAL;
3687 }
3688
3689 pReqMsg = (tpSirEXTScanResetBssidHotlistReqParams)
3690 vos_mem_malloc(sizeof(*pReqMsg));
3691 if (!pReqMsg) {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3693 return -ENOMEM;
3694 }
3695
3696 pReqMsg->requestId = nla_get_u32(
3697 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3699
3700 pReqMsg->sessionId = pAdapter->sessionId;
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3702
3703 status = sme_ResetBssHotlist(pHddCtx->hHal, pReqMsg);
3704 if (!HAL_STATUS_SUCCESS(status)) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR,
3706 FL("sme_ResetBssHotlist failed(err=%d)"), status);
3707 vos_mem_free(pReqMsg);
3708 return -EINVAL;
3709 }
3710
3711 return 0;
3712}
3713
3714static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3715 struct wiphy *wiphy,
3716 struct wireless_dev *wdev,
3717 void *data, int dataLen)
3718{
3719 tpSirEXTScanResetSignificantChangeReqParams pReqMsg = NULL;
3720 struct net_device *dev = wdev->netdev;
3721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3722 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3723 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3724 eHalStatus status;
3725
3726 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3727 status = wlan_hdd_validate_context(pHddCtx);
3728 if (0 != status)
3729 {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 FL("HDD context is not valid"));
3732 return -EINVAL;
3733 }
3734 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3735 data, dataLen,
3736 wlan_hdd_extscan_config_policy)) {
3737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3738 return -EINVAL;
3739 }
3740
3741 /* Parse and fetch request Id */
3742 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3744 return -EINVAL;
3745 }
3746
3747 pReqMsg = (tpSirEXTScanResetSignificantChangeReqParams)
3748 vos_mem_malloc(sizeof(*pReqMsg));
3749 if (!pReqMsg) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3751 return -ENOMEM;
3752 }
3753
3754 pReqMsg->requestId = nla_get_u32(
3755 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3757
3758 pReqMsg->sessionId = pAdapter->sessionId;
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3760
3761 status = sme_ResetSignificantChange(pHddCtx->hHal, pReqMsg);
3762 if (!HAL_STATUS_SUCCESS(status)) {
3763 hddLog(VOS_TRACE_LEVEL_ERROR,
3764 FL("sme_ResetSignificantChange failed(err=%d)"), status);
3765 vos_mem_free(pReqMsg);
3766 return -EINVAL;
3767 }
3768
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3770 return 0;
3771}
3772
3773#endif /* WLAN_FEATURE_EXTSCAN */
3774
Sunil Duttc69bccb2014-05-26 21:30:20 +05303775const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3776{
3777#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3778 {
3779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3782 WIPHY_VENDOR_CMD_NEED_NETDEV |
3783 WIPHY_VENDOR_CMD_NEED_RUNNING,
3784 .doit = wlan_hdd_cfg80211_ll_stats_clear
3785 },
3786
3787 {
3788 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3789 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3790 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3791 WIPHY_VENDOR_CMD_NEED_NETDEV |
3792 WIPHY_VENDOR_CMD_NEED_RUNNING,
3793 .doit = wlan_hdd_cfg80211_ll_stats_set
3794 },
3795
3796 {
3797 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3798 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3799 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3800 WIPHY_VENDOR_CMD_NEED_NETDEV |
3801 WIPHY_VENDOR_CMD_NEED_RUNNING,
3802 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303804#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805#ifdef WLAN_FEATURE_EXTSCAN
3806 {
3807 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3808 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3810 WIPHY_VENDOR_CMD_NEED_NETDEV |
3811 WIPHY_VENDOR_CMD_NEED_RUNNING,
3812 .doit = wlan_hdd_cfg80211_extscan_start
3813 },
3814 {
3815 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3816 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3818 WIPHY_VENDOR_CMD_NEED_NETDEV |
3819 WIPHY_VENDOR_CMD_NEED_RUNNING,
3820 .doit = wlan_hdd_cfg80211_extscan_stop
3821 },
3822 {
3823 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3824 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3826 WIPHY_VENDOR_CMD_NEED_NETDEV,
3827 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3828 },
3829 {
3830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3833 WIPHY_VENDOR_CMD_NEED_NETDEV |
3834 WIPHY_VENDOR_CMD_NEED_RUNNING,
3835 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3836 },
3837 {
3838 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3839 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3840 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3841 WIPHY_VENDOR_CMD_NEED_NETDEV |
3842 WIPHY_VENDOR_CMD_NEED_RUNNING,
3843 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3844 },
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3852 },
3853 {
3854 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3855 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3856 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3857 WIPHY_VENDOR_CMD_NEED_NETDEV |
3858 WIPHY_VENDOR_CMD_NEED_RUNNING,
3859 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3860 },
3861 {
3862 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3863 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3864 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3865 WIPHY_VENDOR_CMD_NEED_NETDEV |
3866 WIPHY_VENDOR_CMD_NEED_RUNNING,
3867 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3868 },
3869 {
3870 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3871 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3872 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3873 WIPHY_VENDOR_CMD_NEED_NETDEV |
3874 WIPHY_VENDOR_CMD_NEED_RUNNING,
3875 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3876 },
3877#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303878};
3879
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003880/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303881static const
3882struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003883{
3884#ifdef FEATURE_WLAN_CH_AVOID
3885 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303886 .vendor_id = QCA_NL80211_VENDOR_ID,
3887 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003888 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303889#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3890#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3891 {
3892 /* Index = 1*/
3893 .vendor_id = QCA_NL80211_VENDOR_ID,
3894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3895 },
3896 {
3897 /* Index = 2*/
3898 .vendor_id = QCA_NL80211_VENDOR_ID,
3899 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3900 },
3901 {
3902 /* Index = 3*/
3903 .vendor_id = QCA_NL80211_VENDOR_ID,
3904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3905 },
3906 {
3907 /* Index = 4*/
3908 .vendor_id = QCA_NL80211_VENDOR_ID,
3909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3910 },
3911 {
3912 /* Index = 5*/
3913 .vendor_id = QCA_NL80211_VENDOR_ID,
3914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3915 },
3916 {
3917 /* Index = 6*/
3918 .vendor_id = QCA_NL80211_VENDOR_ID,
3919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3920 },
3921#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922#ifdef WLAN_FEATURE_EXTSCAN
3923 {
3924 .vendor_id = QCA_NL80211_VENDOR_ID,
3925 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3926 },
3927 {
3928 .vendor_id = QCA_NL80211_VENDOR_ID,
3929 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3930 },
3931 {
3932 .vendor_id = QCA_NL80211_VENDOR_ID,
3933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3934 },
3935 {
3936 .vendor_id = QCA_NL80211_VENDOR_ID,
3937 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3938 },
3939 {
3940 .vendor_id = QCA_NL80211_VENDOR_ID,
3941 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3942 },
3943 {
3944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3946 },
3947 {
3948 .vendor_id = QCA_NL80211_VENDOR_ID,
3949 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
3950 },
3951 {
3952 .vendor_id = QCA_NL80211_VENDOR_ID,
3953 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
3954 },
3955 {
3956 .vendor_id = QCA_NL80211_VENDOR_ID,
3957 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
3958 },
3959 {
3960 .vendor_id = QCA_NL80211_VENDOR_ID,
3961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
3962 },
3963 {
3964 .vendor_id = QCA_NL80211_VENDOR_ID,
3965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
3966 },
3967 {
3968 .vendor_id = QCA_NL80211_VENDOR_ID,
3969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
3970 },
3971 {
3972 .vendor_id = QCA_NL80211_VENDOR_ID,
3973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
3974 },
3975#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303976
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003977};
3978
Jeff Johnson295189b2012-06-20 16:38:30 -07003979/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303980 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303981 * This function is called by hdd_wlan_startup()
3982 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303983 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05303985struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07003986{
3987 struct wiphy *wiphy;
3988 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303989 /*
3990 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 */
3992 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
3993
3994 if (!wiphy)
3995 {
3996 /* Print error and jump into err label and free the memory */
3997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
3998 return NULL;
3999 }
4000
Sunil Duttc69bccb2014-05-26 21:30:20 +05304001
Jeff Johnson295189b2012-06-20 16:38:30 -07004002 return wiphy;
4003}
4004
4005/*
4006 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 * private ioctl to change the band value
4009 */
4010int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4011{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304012 int i, j;
4013 eNVChannelEnabledType channelEnabledState;
4014
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304016
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304017 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304019
4020 if (NULL == wiphy->bands[i])
4021 {
4022 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4023 __func__, i);
4024 continue;
4025 }
4026
4027 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4028 {
4029 struct ieee80211_supported_band *band = wiphy->bands[i];
4030
4031 channelEnabledState = vos_nv_getChannelEnabledState(
4032 band->channels[j].hw_value);
4033
4034 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4035 {
4036 // Enable Social channels for P2P
4037 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4038 NV_CHANNEL_ENABLE == channelEnabledState)
4039 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4040 else
4041 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4042 continue;
4043 }
4044 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4045 {
4046 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4047 continue;
4048 }
4049
4050 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4051 NV_CHANNEL_INVALID == channelEnabledState)
4052 {
4053 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4054 }
4055 else if (NV_CHANNEL_DFS == channelEnabledState)
4056 {
4057 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4058 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4059 }
4060 else
4061 {
4062 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4063 |IEEE80211_CHAN_RADAR);
4064 }
4065 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 }
4067 return 0;
4068}
4069/*
4070 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 * This function is called by hdd_wlan_startup()
4072 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004073 * This function is used to initialize and register wiphy structure.
4074 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304075int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 struct wiphy *wiphy,
4077 hdd_config_t *pCfg
4078 )
4079{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304080 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304081 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4082
Jeff Johnsone7245742012-09-05 17:12:55 -07004083 ENTER();
4084
Jeff Johnson295189b2012-06-20 16:38:30 -07004085 /* Now bind the underlying wlan device with wiphy */
4086 set_wiphy_dev(wiphy, dev);
4087
4088 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004089
Kiet Lam6c583332013-10-14 05:37:09 +05304090#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004091 /* the flag for the other case would be initialzed in
4092 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004093 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304094#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004095
Amar Singhalfddc28c2013-09-05 13:03:40 -07004096 /* This will disable updating of NL channels from passive to
4097 * active if a beacon is received on passive channel. */
4098 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004099
Amar Singhalfddc28c2013-09-05 13:03:40 -07004100
Amar Singhala49cbc52013-10-08 18:37:44 -07004101
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004103 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4104 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4105 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004106 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304107 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004109
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004111 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004112#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004113 || pCfg->isFastRoamIniFeatureEnabled
4114#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004115#ifdef FEATURE_WLAN_ESE
4116 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004117#endif
4118 )
4119 {
4120 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4121 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004122#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004123#ifdef FEATURE_WLAN_TDLS
4124 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4125 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4126#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304127#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304128 if (pCfg->configPNOScanSupport)
4129 {
4130 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4131 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4132 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4133 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4134 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304135#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004136
Amar Singhalfddc28c2013-09-05 13:03:40 -07004137#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004138 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4139 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004141 driver need to determine what to do with both
4142 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004143
4144 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004145#else
4146 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004148
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4150
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304151 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004152
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304153 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4154
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4159 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004160 | BIT(NL80211_IFTYPE_AP);
4161
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304162 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004163 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4165 if( pCfg->enableMCC )
4166 {
4167 /* Currently, supports up to two channels */
4168 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004169
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304170 if( !pCfg->allowMCCGODiffBI )
4171 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004172
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304173 }
4174 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4175 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004176#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304177 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004178
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 /* Before registering we need to update the ht capabilitied based
4180 * on ini values*/
4181 if( !pCfg->ShortGI20MhzEnable )
4182 {
4183 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4184 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4185 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4186 }
4187
4188 if( !pCfg->ShortGI40MhzEnable )
4189 {
4190 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4191 }
4192
4193 if( !pCfg->nChannelBondingMode5GHz )
4194 {
4195 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4196 }
4197
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304198 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304199 if (true == hdd_is_5g_supported(pHddCtx))
4200 {
4201 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4202 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304203
4204 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4205 {
4206
4207 if (NULL == wiphy->bands[i])
4208 {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4210 __func__, i);
4211 continue;
4212 }
4213
4214 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4215 {
4216 struct ieee80211_supported_band *band = wiphy->bands[i];
4217
4218 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4219 {
4220 // Enable social channels for P2P
4221 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4222 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4223 else
4224 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4225 continue;
4226 }
4227 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4228 {
4229 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4230 continue;
4231 }
4232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 }
4234 /*Initialise the supported cipher suite details*/
4235 wiphy->cipher_suites = hdd_cipher_suites;
4236 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4237
4238 /*signal strength in mBm (100*dBm) */
4239 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4240
4241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 wiphy->max_remain_on_channel_duration = 1000;
4243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
Sunil Duttc69bccb2014-05-26 21:30:20 +05304245 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4246 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004247 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4248 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4249
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304250 EXIT();
4251 return 0;
4252}
4253
4254/* In this function we are registering wiphy. */
4255int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4256{
4257 ENTER();
4258 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 if (0 > wiphy_register(wiphy))
4260 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304261 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4263 return -EIO;
4264 }
4265
4266 EXIT();
4267 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268}
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304270/* In this function we are updating channel list when,
4271 regulatory domain is FCC and country code is US.
4272 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4273 As per FCC smart phone is not a indoor device.
4274 GO should not opeate on indoor channels */
4275void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4276{
4277 int j;
4278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4279 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4280 //Default counrtycode from NV at the time of wiphy initialization.
4281 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4282 &defaultCountryCode[0]))
4283 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004284 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304285 }
4286 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4287 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304288 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4291 return;
4292 }
4293 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4294 {
4295 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4296 // Mark UNII -1 band channel as passive
4297 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4298 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4299 }
4300 }
4301}
4302
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304303/* This function registers for all frame which supplicant is interested in */
4304void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004305{
Jeff Johnson295189b2012-06-20 16:38:30 -07004306 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4307 /* Register for all P2P action, public action etc frames */
4308 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4309
Jeff Johnsone7245742012-09-05 17:12:55 -07004310 ENTER();
4311
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 /* Right now we are registering these frame when driver is getting
4313 initialized. Once we will move to 2.6.37 kernel, in which we have
4314 frame register ops, we will move this code as a part of that */
4315 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4318
4319 /* GAS Initial Response */
4320 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4321 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304322
Jeff Johnson295189b2012-06-20 16:38:30 -07004323 /* GAS Comeback Request */
4324 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4325 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4326
4327 /* GAS Comeback Response */
4328 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4329 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4330
4331 /* P2P Public Action */
4332 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304333 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004334 P2P_PUBLIC_ACTION_FRAME_SIZE );
4335
4336 /* P2P Action */
4337 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4338 (v_U8_t*)P2P_ACTION_FRAME,
4339 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004340
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304341 /* WNM BSS Transition Request frame */
4342 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4343 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4344 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004345
4346 /* WNM-Notification */
4347 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4348 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4349 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004350}
4351
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304352void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004353{
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4355 /* Register for all P2P action, public action etc frames */
4356 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4357
Jeff Johnsone7245742012-09-05 17:12:55 -07004358 ENTER();
4359
Jeff Johnson295189b2012-06-20 16:38:30 -07004360 /* Right now we are registering these frame when driver is getting
4361 initialized. Once we will move to 2.6.37 kernel, in which we have
4362 frame register ops, we will move this code as a part of that */
4363 /* GAS Initial Request */
4364
4365 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4366 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4367
4368 /* GAS Initial Response */
4369 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4370 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304371
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 /* GAS Comeback Request */
4373 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4374 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4375
4376 /* GAS Comeback Response */
4377 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4378 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4379
4380 /* P2P Public Action */
4381 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304382 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 P2P_PUBLIC_ACTION_FRAME_SIZE );
4384
4385 /* P2P Action */
4386 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4387 (v_U8_t*)P2P_ACTION_FRAME,
4388 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004389 /* WNM-Notification */
4390 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4391 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4392 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004393}
4394
4395#ifdef FEATURE_WLAN_WAPI
4396void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4397 const u8 *mac_addr, u8 *key , int key_Len)
4398{
4399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4400 tCsrRoamSetKey setKey;
4401 v_BOOL_t isConnected = TRUE;
4402 int status = 0;
4403 v_U32_t roamId= 0xFF;
4404 tANI_U8 *pKeyPtr = NULL;
4405 int n = 0;
4406
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304407 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4408 __func__, hdd_device_modetoString(pAdapter->device_mode),
4409 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004410
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304411 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 setKey.keyId = key_index; // Store Key ID
4413 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4414 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4415 setKey.paeRole = 0 ; // the PAE role
4416 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4417 {
4418 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4419 }
4420 else
4421 {
4422 isConnected = hdd_connIsConnected(pHddStaCtx);
4423 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4424 }
4425 setKey.keyLength = key_Len;
4426 pKeyPtr = setKey.Key;
4427 memcpy( pKeyPtr, key, key_Len);
4428
Arif Hussain6d2a3322013-11-17 19:50:10 -08004429 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 __func__, key_Len);
4431 for (n = 0 ; n < key_Len; n++)
4432 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4433 __func__,n,setKey.Key[n]);
4434
4435 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4436 if ( isConnected )
4437 {
4438 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4439 pAdapter->sessionId, &setKey, &roamId );
4440 }
4441 if ( status != 0 )
4442 {
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4444 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4445 __LINE__, status );
4446 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4447 }
4448}
4449#endif /* FEATURE_WLAN_WAPI*/
4450
4451#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304452int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 beacon_data_t **ppBeacon,
4454 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004455#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304456int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004457 beacon_data_t **ppBeacon,
4458 struct cfg80211_beacon_data *params,
4459 int dtim_period)
4460#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304461{
Jeff Johnson295189b2012-06-20 16:38:30 -07004462 int size;
4463 beacon_data_t *beacon = NULL;
4464 beacon_data_t *old = NULL;
4465 int head_len,tail_len;
4466
Jeff Johnsone7245742012-09-05 17:12:55 -07004467 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304469 {
4470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4471 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004472 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004474
4475 old = pAdapter->sessionCtx.ap.beacon;
4476
4477 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304478 {
4479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4480 FL("session(%d) old and new heads points to NULL"),
4481 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004482 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304483 }
4484
4485 if (params->tail && !params->tail_len)
4486 {
4487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4488 FL("tail_len is zero but tail is not NULL"));
4489 return -EINVAL;
4490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004491
Jeff Johnson295189b2012-06-20 16:38:30 -07004492#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4493 /* Kernel 3.0 is not updating dtim_period for set beacon */
4494 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304495 {
4496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4497 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004498 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004500#endif
4501
4502 if(params->head)
4503 head_len = params->head_len;
4504 else
4505 head_len = old->head_len;
4506
4507 if(params->tail || !old)
4508 tail_len = params->tail_len;
4509 else
4510 tail_len = old->tail_len;
4511
4512 size = sizeof(beacon_data_t) + head_len + tail_len;
4513
4514 beacon = kzalloc(size, GFP_KERNEL);
4515
4516 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304517 {
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4519 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004522
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004523#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 if(params->dtim_period || !old )
4525 beacon->dtim_period = params->dtim_period;
4526 else
4527 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004528#else
4529 if(dtim_period || !old )
4530 beacon->dtim_period = dtim_period;
4531 else
4532 beacon->dtim_period = old->dtim_period;
4533#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304534
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4536 beacon->tail = beacon->head + head_len;
4537 beacon->head_len = head_len;
4538 beacon->tail_len = tail_len;
4539
4540 if(params->head) {
4541 memcpy (beacon->head,params->head,beacon->head_len);
4542 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304543 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 if(old)
4545 memcpy (beacon->head,old->head,beacon->head_len);
4546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304547
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 if(params->tail) {
4549 memcpy (beacon->tail,params->tail,beacon->tail_len);
4550 }
4551 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304552 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 memcpy (beacon->tail,old->tail,beacon->tail_len);
4554 }
4555
4556 *ppBeacon = beacon;
4557
4558 kfree(old);
4559
4560 return 0;
4561
4562}
Jeff Johnson295189b2012-06-20 16:38:30 -07004563
4564v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4565{
4566 int left = length;
4567 v_U8_t *ptr = pIes;
4568 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304569
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 elem_id = ptr[0];
4573 elem_len = ptr[1];
4574 left -= 2;
4575 if(elem_len > left)
4576 {
4577 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004578 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004579 eid,elem_len,left);
4580 return NULL;
4581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304582 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 {
4584 return ptr;
4585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304586
Jeff Johnson295189b2012-06-20 16:38:30 -07004587 left -= elem_len;
4588 ptr += (elem_len + 2);
4589 }
4590 return NULL;
4591}
4592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593/* Check if rate is 11g rate or not */
4594static int wlan_hdd_rate_is_11g(u8 rate)
4595{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004596 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 u8 i;
4598 for (i = 0; i < 8; i++)
4599 {
4600 if(rate == gRateArray[i])
4601 return TRUE;
4602 }
4603 return FALSE;
4604}
4605
4606/* Check for 11g rate and set proper 11g only mode */
4607static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4608 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4609{
4610 u8 i, num_rates = pIe[0];
4611
4612 pIe += 1;
4613 for ( i = 0; i < num_rates; i++)
4614 {
4615 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4616 {
4617 /* If rate set have 11g rate than change the mode to 11G */
4618 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4619 if (pIe[i] & BASIC_RATE_MASK)
4620 {
4621 /* If we have 11g rate as basic rate, it means mode
4622 is 11g only mode.
4623 */
4624 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4625 *pCheckRatesfor11g = FALSE;
4626 }
4627 }
4628 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4629 {
4630 *require_ht = TRUE;
4631 }
4632 }
4633 return;
4634}
4635
4636static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4637{
4638 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4639 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4640 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4641 u8 checkRatesfor11g = TRUE;
4642 u8 require_ht = FALSE;
4643 u8 *pIe=NULL;
4644
4645 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4646
4647 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4648 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4649 if (pIe != NULL)
4650 {
4651 pIe += 1;
4652 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4653 &pConfig->SapHw_mode);
4654 }
4655
4656 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4657 WLAN_EID_EXT_SUPP_RATES);
4658 if (pIe != NULL)
4659 {
4660
4661 pIe += 1;
4662 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4663 &pConfig->SapHw_mode);
4664 }
4665
4666 if( pConfig->channel > 14 )
4667 {
4668 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4669 }
4670
4671 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4672 WLAN_EID_HT_CAPABILITY);
4673
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304674 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 {
4676 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4677 if(require_ht)
4678 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4679 }
4680}
4681
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304682static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4683 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4684{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004685 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304686 v_U8_t *pIe = NULL;
4687 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4688
4689 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4690 pBeacon->tail, pBeacon->tail_len);
4691
4692 if (pIe)
4693 {
4694 ielen = pIe[1] + 2;
4695 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4696 {
4697 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4698 }
4699 else
4700 {
4701 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4702 return -EINVAL;
4703 }
4704 *total_ielen += ielen;
4705 }
4706 return 0;
4707}
4708
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004709static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4710 v_U8_t *genie, v_U8_t *total_ielen)
4711{
4712 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4713 int left = pBeacon->tail_len;
4714 v_U8_t *ptr = pBeacon->tail;
4715 v_U8_t elem_id, elem_len;
4716 v_U16_t ielen = 0;
4717
4718 if ( NULL == ptr || 0 == left )
4719 return;
4720
4721 while (left >= 2)
4722 {
4723 elem_id = ptr[0];
4724 elem_len = ptr[1];
4725 left -= 2;
4726 if (elem_len > left)
4727 {
4728 hddLog( VOS_TRACE_LEVEL_ERROR,
4729 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4730 elem_id, elem_len, left);
4731 return;
4732 }
4733 if (IE_EID_VENDOR == elem_id)
4734 {
4735 /* skipping the VSIE's which we don't want to include or
4736 * it will be included by existing code
4737 */
4738 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4739#ifdef WLAN_FEATURE_WFD
4740 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4741#endif
4742 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4743 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4744 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4745 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4746 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4747 {
4748 ielen = ptr[1] + 2;
4749 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4750 {
4751 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4752 *total_ielen += ielen;
4753 }
4754 else
4755 {
4756 hddLog( VOS_TRACE_LEVEL_ERROR,
4757 "IE Length is too big "
4758 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4759 elem_id, elem_len, *total_ielen);
4760 }
4761 }
4762 }
4763
4764 left -= elem_len;
4765 ptr += (elem_len + 2);
4766 }
4767 return;
4768}
4769
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004770#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004771static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4772 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004773#else
4774static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4775 struct cfg80211_beacon_data *params)
4776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004777{
4778 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304779 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004781 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004782
4783 genie = vos_mem_malloc(MAX_GENIE_LEN);
4784
4785 if(genie == NULL) {
4786
4787 return -ENOMEM;
4788 }
4789
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304790 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4791 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304793 hddLog(LOGE,
4794 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304795 ret = -EINVAL;
4796 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004797 }
4798
4799#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304800 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4801 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4802 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304803 hddLog(LOGE,
4804 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304805 ret = -EINVAL;
4806 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 }
4808#endif
4809
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304810 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4811 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004812 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304813 hddLog(LOGE,
4814 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304815 ret = -EINVAL;
4816 goto done;
4817 }
4818
Abhishek Singh5128c4f2014-06-04 14:48:31 +05304819 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4820 &total_ielen, WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE))
4821 {
4822 hddLog(LOGE, FL("Adding WMM IE failed"));
4823 ret = -EINVAL;
4824 goto done;
4825 }
4826
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304827 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4828 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004829 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004831
4832 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4833 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4834 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4835 {
4836 hddLog(LOGE,
4837 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004838 ret = -EINVAL;
4839 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 }
4841
4842 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4843 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4844 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4845 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4846 ==eHAL_STATUS_FAILURE)
4847 {
4848 hddLog(LOGE,
4849 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004850 ret = -EINVAL;
4851 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 }
4853
4854 // Added for ProResp IE
4855 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4856 {
4857 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4858 u8 probe_rsp_ie_len[3] = {0};
4859 u8 counter = 0;
4860 /* Check Probe Resp Length if it is greater then 255 then Store
4861 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4862 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4863 Store More then 255 bytes into One Variable.
4864 */
4865 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4866 {
4867 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4868 {
4869 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4870 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4871 }
4872 else
4873 {
4874 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4875 rem_probe_resp_ie_len = 0;
4876 }
4877 }
4878
4879 rem_probe_resp_ie_len = 0;
4880
4881 if (probe_rsp_ie_len[0] > 0)
4882 {
4883 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4884 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4885 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4886 probe_rsp_ie_len[0], NULL,
4887 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4888 {
4889 hddLog(LOGE,
4890 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004891 ret = -EINVAL;
4892 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 }
4894 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4895 }
4896
4897 if (probe_rsp_ie_len[1] > 0)
4898 {
4899 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4900 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4901 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4902 probe_rsp_ie_len[1], NULL,
4903 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4904 {
4905 hddLog(LOGE,
4906 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004907 ret = -EINVAL;
4908 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004909 }
4910 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4911 }
4912
4913 if (probe_rsp_ie_len[2] > 0)
4914 {
4915 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4916 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4917 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4918 probe_rsp_ie_len[2], NULL,
4919 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4920 {
4921 hddLog(LOGE,
4922 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004923 ret = -EINVAL;
4924 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 }
4926 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4927 }
4928
4929 if (probe_rsp_ie_len[1] == 0 )
4930 {
4931 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4932 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4933 eANI_BOOLEAN_FALSE) )
4934 {
4935 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004936 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004937 }
4938 }
4939
4940 if (probe_rsp_ie_len[2] == 0 )
4941 {
4942 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4944 eANI_BOOLEAN_FALSE) )
4945 {
4946 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004947 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 }
4949 }
4950
4951 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4952 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4953 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4954 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4955 == eHAL_STATUS_FAILURE)
4956 {
4957 hddLog(LOGE,
4958 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004959 ret = -EINVAL;
4960 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 }
4962 }
4963 else
4964 {
4965 // Reset WNI_CFG_PROBE_RSP Flags
4966 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
4967
4968 hddLog(VOS_TRACE_LEVEL_INFO,
4969 "%s: No Probe Response IE received in set beacon",
4970 __func__);
4971 }
4972
4973 // Added for AssocResp IE
4974 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
4975 {
4976 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4977 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
4978 params->assocresp_ies_len, NULL,
4979 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4980 {
4981 hddLog(LOGE,
4982 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004983 ret = -EINVAL;
4984 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 }
4986
4987 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4988 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
4989 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4990 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4991 == eHAL_STATUS_FAILURE)
4992 {
4993 hddLog(LOGE,
4994 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004995 ret = -EINVAL;
4996 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 }
4998 }
4999 else
5000 {
5001 hddLog(VOS_TRACE_LEVEL_INFO,
5002 "%s: No Assoc Response IE received in set beacon",
5003 __func__);
5004
5005 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5006 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5007 eANI_BOOLEAN_FALSE) )
5008 {
5009 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005010 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 }
5012 }
5013
Jeff Johnsone7245742012-09-05 17:12:55 -07005014done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305016 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005017}
Jeff Johnson295189b2012-06-20 16:38:30 -07005018
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305019/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 * FUNCTION: wlan_hdd_validate_operation_channel
5021 * called by wlan_hdd_cfg80211_start_bss() and
5022 * wlan_hdd_cfg80211_set_channel()
5023 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305024 * channel list.
5025 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005026VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005027{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305028
Jeff Johnson295189b2012-06-20 16:38:30 -07005029 v_U32_t num_ch = 0;
5030 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5031 u32 indx = 0;
5032 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305033 v_U8_t fValidChannel = FALSE, count = 0;
5034 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305035
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5037
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305038 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305040 /* Validate the channel */
5041 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305043 if ( channel == rfChannels[count].channelNum )
5044 {
5045 fValidChannel = TRUE;
5046 break;
5047 }
5048 }
5049 if (fValidChannel != TRUE)
5050 {
5051 hddLog(VOS_TRACE_LEVEL_ERROR,
5052 "%s: Invalid Channel [%d]", __func__, channel);
5053 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 }
5055 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305056 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305058 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5059 valid_ch, &num_ch))
5060 {
5061 hddLog(VOS_TRACE_LEVEL_ERROR,
5062 "%s: failed to get valid channel list", __func__);
5063 return VOS_STATUS_E_FAILURE;
5064 }
5065 for (indx = 0; indx < num_ch; indx++)
5066 {
5067 if (channel == valid_ch[indx])
5068 {
5069 break;
5070 }
5071 }
5072
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305073 if (indx >= num_ch)
5074 {
5075 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5076 {
5077 eCsrBand band;
5078 unsigned int freq;
5079
5080 sme_GetFreqBand(hHal, &band);
5081
5082 if (eCSR_BAND_5G == band)
5083 {
5084#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5085 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5086 {
5087 freq = ieee80211_channel_to_frequency(channel,
5088 IEEE80211_BAND_2GHZ);
5089 }
5090 else
5091 {
5092 freq = ieee80211_channel_to_frequency(channel,
5093 IEEE80211_BAND_5GHZ);
5094 }
5095#else
5096 freq = ieee80211_channel_to_frequency(channel);
5097#endif
5098 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5099 return VOS_STATUS_SUCCESS;
5100 }
5101 }
5102
5103 hddLog(VOS_TRACE_LEVEL_ERROR,
5104 "%s: Invalid Channel [%d]", __func__, channel);
5105 return VOS_STATUS_E_FAILURE;
5106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005107 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305108
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305110
Jeff Johnson295189b2012-06-20 16:38:30 -07005111}
5112
Viral Modi3a32cc52013-02-08 11:14:52 -08005113/**
5114 * FUNCTION: wlan_hdd_cfg80211_set_channel
5115 * This function is used to set the channel number
5116 */
5117static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5118 struct ieee80211_channel *chan,
5119 enum nl80211_channel_type channel_type
5120 )
5121{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305122 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005123 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005124 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005125 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305126 hdd_context_t *pHddCtx;
5127 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005128
5129 ENTER();
5130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305131
Viral Modi3a32cc52013-02-08 11:14:52 -08005132 if( NULL == dev )
5133 {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005135 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005136 return -ENODEV;
5137 }
5138 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5139
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305140 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5141 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5142 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005143 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305144 "%s: device_mode = %s (%d) freq = %d", __func__,
5145 hdd_device_modetoString(pAdapter->device_mode),
5146 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305147
5148 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5149 status = wlan_hdd_validate_context(pHddCtx);
5150
5151 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005152 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5154 "%s: HDD context is not valid", __func__);
5155 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005156 }
5157
5158 /*
5159 * Do freq to chan conversion
5160 * TODO: for 11a
5161 */
5162
5163 channel = ieee80211_frequency_to_channel(freq);
5164
5165 /* Check freq range */
5166 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5167 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5168 {
5169 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005170 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005171 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5172 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5173 return -EINVAL;
5174 }
5175
5176 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5177
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305178 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5179 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005180 {
5181 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5182 {
5183 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005184 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005185 return -EINVAL;
5186 }
5187 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5188 "%s: set channel to [%d] for device mode =%d",
5189 __func__, channel,pAdapter->device_mode);
5190 }
5191 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005192 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005193 )
5194 {
5195 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5196 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5197 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5198
5199 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5200 {
5201 /* Link is up then return cant set channel*/
5202 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005203 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005204 return -EINVAL;
5205 }
5206
5207 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5208 pHddStaCtx->conn_info.operationChannel = channel;
5209 pRoamProfile->ChannelInfo.ChannelList =
5210 &pHddStaCtx->conn_info.operationChannel;
5211 }
5212 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005213 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005214 )
5215 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305216 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5217 {
5218 if(VOS_STATUS_SUCCESS !=
5219 wlan_hdd_validate_operation_channel(pAdapter,channel))
5220 {
5221 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005222 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305223 return -EINVAL;
5224 }
5225 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5226 }
5227 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005228 {
5229 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5230
5231 /* If auto channel selection is configured as enable/ 1 then ignore
5232 channel set by supplicant
5233 */
5234 if ( cfg_param->apAutoChannelSelection )
5235 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305236 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5237 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005238 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305239 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5240 __func__, hdd_device_modetoString(pAdapter->device_mode),
5241 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005242 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305243 else
5244 {
5245 if(VOS_STATUS_SUCCESS !=
5246 wlan_hdd_validate_operation_channel(pAdapter,channel))
5247 {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005249 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305250 return -EINVAL;
5251 }
5252 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5253 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005254 }
5255 }
5256 else
5257 {
5258 hddLog(VOS_TRACE_LEVEL_FATAL,
5259 "%s: Invalid device mode failed to set valid channel", __func__);
5260 return -EINVAL;
5261 }
5262 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305263 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005264}
5265
Jeff Johnson295189b2012-06-20 16:38:30 -07005266#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5267static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5268 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005269#else
5270static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5271 struct cfg80211_beacon_data *params,
5272 const u8 *ssid, size_t ssid_len,
5273 enum nl80211_hidden_ssid hidden_ssid)
5274#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005275{
5276 tsap_Config_t *pConfig;
5277 beacon_data_t *pBeacon = NULL;
5278 struct ieee80211_mgmt *pMgmt_frame;
5279 v_U8_t *pIe=NULL;
5280 v_U16_t capab_info;
5281 eCsrAuthType RSNAuthType;
5282 eCsrEncryptionType RSNEncryptType;
5283 eCsrEncryptionType mcRSNEncryptType;
5284 int status = VOS_STATUS_SUCCESS;
5285 tpWLAN_SAPEventCB pSapEventCallback;
5286 hdd_hostapd_state_t *pHostapdState;
5287 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5288 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305289 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305291 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005292 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005293 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005294 v_BOOL_t MFPCapable = VOS_FALSE;
5295 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305296 eHddDot11Mode sapDot11Mode =
5297 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005298
5299 ENTER();
5300
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305301 iniConfig = pHddCtx->cfg_ini;
5302
Jeff Johnson295189b2012-06-20 16:38:30 -07005303 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5304
5305 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5306
5307 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5308
5309 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5310
5311 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5312
5313 //channel is already set in the set_channel Call back
5314 //pConfig->channel = pCommitConfig->channel;
5315
5316 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305317 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5319
5320 pConfig->dtim_period = pBeacon->dtim_period;
5321
Arif Hussain6d2a3322013-11-17 19:50:10 -08005322 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 pConfig->dtim_period);
5324
5325
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005326 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005327 {
5328 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005329 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305330 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5331 {
5332 tANI_BOOLEAN restartNeeded;
5333 pConfig->ieee80211d = 1;
5334 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5335 sme_setRegInfo(hHal, pConfig->countryCode);
5336 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5337 }
5338 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005340 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005341 pConfig->ieee80211d = 1;
5342 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5343 sme_setRegInfo(hHal, pConfig->countryCode);
5344 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005346 else
5347 {
5348 pConfig->ieee80211d = 0;
5349 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305350 /*
5351 * If auto channel is configured i.e. channel is 0,
5352 * so skip channel validation.
5353 */
5354 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5355 {
5356 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5357 {
5358 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005359 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305360 return -EINVAL;
5361 }
5362 }
5363 else
5364 {
5365 if(1 != pHddCtx->is_dynamic_channel_range_set)
5366 {
5367 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5368 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5369 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5370 }
5371 pHddCtx->is_dynamic_channel_range_set = 0;
5372 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005374 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 {
5376 pConfig->ieee80211d = 0;
5377 }
5378 pConfig->authType = eSAP_AUTO_SWITCH;
5379
5380 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305381
5382 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5384
5385 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5386
5387 /*Set wps station to configured*/
5388 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5389
5390 if(pIe)
5391 {
5392 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5393 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005394 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 return -EINVAL;
5396 }
5397 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5398 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005399 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 /* Check 15 bit of WPS IE as it contain information for wps state
5401 * WPS state
5402 */
5403 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5404 {
5405 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5406 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5407 {
5408 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5409 }
5410 }
5411 }
5412 else
5413 {
5414 pConfig->wps_state = SAP_WPS_DISABLED;
5415 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305416 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005417
c_hpothufe599e92014-06-16 11:38:55 +05305418 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5419 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5420 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5421 eCSR_ENCRYPT_TYPE_NONE;
5422
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 pConfig->RSNWPAReqIELength = 0;
5424 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305425 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 WLAN_EID_RSN);
5427 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305428 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5430 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5431 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305432 /* The actual processing may eventually be more extensive than
5433 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 * by the app.
5435 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305436 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5438 &RSNEncryptType,
5439 &mcRSNEncryptType,
5440 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005441 &MFPCapable,
5442 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 pConfig->pRSNWPAReqIE[1]+2,
5444 pConfig->pRSNWPAReqIE );
5445
5446 if( VOS_STATUS_SUCCESS == status )
5447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305448 /* Now copy over all the security attributes you have
5449 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005450 * */
5451 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5452 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5453 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5454 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305455 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005456 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005457 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5458 }
5459 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305460
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5462 pBeacon->tail, pBeacon->tail_len);
5463
5464 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5465 {
5466 if (pConfig->pRSNWPAReqIE)
5467 {
5468 /*Mixed mode WPA/WPA2*/
5469 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5470 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5471 }
5472 else
5473 {
5474 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5475 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5476 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305477 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5479 &RSNEncryptType,
5480 &mcRSNEncryptType,
5481 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005482 &MFPCapable,
5483 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005484 pConfig->pRSNWPAReqIE[1]+2,
5485 pConfig->pRSNWPAReqIE );
5486
5487 if( VOS_STATUS_SUCCESS == status )
5488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305489 /* Now copy over all the security attributes you have
5490 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 * */
5492 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5493 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5494 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5495 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305496 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005497 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5499 }
5500 }
5501 }
5502
Jeff Johnson4416a782013-03-25 14:17:50 -07005503 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5504 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5505 return -EINVAL;
5506 }
5507
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5509
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005510#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 if (params->ssid != NULL)
5512 {
5513 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5514 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5515 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5516 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5517 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005518#else
5519 if (ssid != NULL)
5520 {
5521 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5522 pConfig->SSIDinfo.ssid.length = ssid_len;
5523 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5524 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5525 }
5526#endif
5527
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305528 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305530
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 /* default value */
5532 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5533 pConfig->num_accept_mac = 0;
5534 pConfig->num_deny_mac = 0;
5535
5536 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5537 pBeacon->tail, pBeacon->tail_len);
5538
5539 /* pIe for black list is following form:
5540 type : 1 byte
5541 length : 1 byte
5542 OUI : 4 bytes
5543 acl type : 1 byte
5544 no of mac addr in black list: 1 byte
5545 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305546 */
5547 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 {
5549 pConfig->SapMacaddr_acl = pIe[6];
5550 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005551 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305553 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5554 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5556 for (i = 0; i < pConfig->num_deny_mac; i++)
5557 {
5558 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5559 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305560 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 }
5562 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5563 pBeacon->tail, pBeacon->tail_len);
5564
5565 /* pIe for white list is following form:
5566 type : 1 byte
5567 length : 1 byte
5568 OUI : 4 bytes
5569 acl type : 1 byte
5570 no of mac addr in white list: 1 byte
5571 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305572 */
5573 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 {
5575 pConfig->SapMacaddr_acl = pIe[6];
5576 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005577 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305579 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5580 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5582 for (i = 0; i < pConfig->num_accept_mac; i++)
5583 {
5584 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5585 acl_entry++;
5586 }
5587 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305588
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5590
Jeff Johnsone7245742012-09-05 17:12:55 -07005591#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005592 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305593 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5594 * 11ac in .ini and 11ac is supported by both host and firmware.
5595 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5596 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005597 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5598 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305599 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5600 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5601 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5602 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5603 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005604 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305605 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005606 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305607 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005608
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305609 /* If ACS disable and selected channel <= 14
5610 * OR
5611 * ACS enabled and ACS operating band is choosen as 2.4
5612 * AND
5613 * VHT in 2.4G Disabled
5614 * THEN
5615 * Fallback to 11N mode
5616 */
5617 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5618 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305619 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305620 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005621 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305622 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5623 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005624 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5625 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005626 }
5627#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305628
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005629 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5630 {
5631 sme_SelectCBMode(hHal,
5632 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5633 pConfig->channel);
5634 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 // ht_capab is not what the name conveys,this is used for protection bitmap
5636 pConfig->ht_capab =
5637 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5638
5639 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5640 {
5641 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5642 return -EINVAL;
5643 }
5644
5645 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5648 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305649 pConfig->obssProtEnabled =
5650 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005651
Chet Lanctot8cecea22014-02-11 19:09:36 -08005652#ifdef WLAN_FEATURE_11W
5653 pConfig->mfpCapable = MFPCapable;
5654 pConfig->mfpRequired = MFPRequired;
5655 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5656 pConfig->mfpCapable, pConfig->mfpRequired);
5657#endif
5658
Arif Hussain6d2a3322013-11-17 19:50:10 -08005659 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005661 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5662 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5663 (int)pConfig->channel);
5664 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5665 pConfig->SapHw_mode, pConfig->privacy,
5666 pConfig->authType);
5667 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5668 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5669 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5670 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305672 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005673 {
5674 //Bss already started. just return.
5675 //TODO Probably it should update some beacon params.
5676 hddLog( LOGE, "Bss Already started...Ignore the request");
5677 EXIT();
5678 return 0;
5679 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305680
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 pConfig->persona = pHostapdAdapter->device_mode;
5682
5683 pSapEventCallback = hdd_hostapd_SAPEventCB;
5684 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5685 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5686 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005687 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 return -EINVAL;
5689 }
5690
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305691 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5693
5694 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305695
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305697 {
5698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005699 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005700 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 VOS_ASSERT(0);
5702 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305703
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5705
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005706#ifdef WLAN_FEATURE_P2P_DEBUG
5707 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5708 {
5709 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5710 {
5711 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5712 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005713 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005714 }
5715 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5716 {
5717 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5718 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005719 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005720 }
5721 }
5722#endif
5723
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 pHostapdState->bCommit = TRUE;
5725 EXIT();
5726
5727 return 0;
5728}
5729
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005730#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5732 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 struct beacon_parameters *params)
5734{
5735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305736 hdd_context_t *pHddCtx;
5737 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005738
5739 ENTER();
5740
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5742 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5743 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305744 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5745 hdd_device_modetoString(pAdapter->device_mode),
5746 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005747
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305748 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5749 status = wlan_hdd_validate_context(pHddCtx);
5750
5751 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5754 "%s: HDD context is not valid", __func__);
5755 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005756 }
5757
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305758 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 )
5761 {
5762 beacon_data_t *old,*new;
5763
5764 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305765
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305767 {
5768 hddLog(VOS_TRACE_LEVEL_WARN,
5769 FL("already beacon info added to session(%d)"),
5770 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305772 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005773
5774 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5775
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 {
5778 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005779 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 return -EINVAL;
5781 }
5782
5783 pAdapter->sessionCtx.ap.beacon = new;
5784
5785 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5786 }
5787
5788 EXIT();
5789 return status;
5790}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305791
5792static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 struct net_device *dev,
5794 struct beacon_parameters *params)
5795{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305797 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305798 hdd_context_t *pHddCtx;
5799 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005800
5801 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305802 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5803 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5804 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5806 __func__, hdd_device_modetoString(pAdapter->device_mode),
5807 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005808
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5810 status = wlan_hdd_validate_context(pHddCtx);
5811
5812 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005813 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5815 "%s: HDD context is not valid", __func__);
5816 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005817 }
5818
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 {
5823 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305828 {
5829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5830 FL("session(%d) old and new heads points to NULL"),
5831 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305833 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005834
5835 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5836
5837 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305838 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005839 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 return -EINVAL;
5841 }
5842
5843 pAdapter->sessionCtx.ap.beacon = new;
5844
5845 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5846 }
5847
5848 EXIT();
5849 return status;
5850}
5851
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005852#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5853
5854#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005855static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5856 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005857#else
5858static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5859 struct net_device *dev)
5860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005861{
5862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005863 hdd_context_t *pHddCtx = NULL;
5864 hdd_scaninfo_t *pScanInfo = NULL;
5865 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305866 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305867 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005868
5869 ENTER();
5870
5871 if (NULL == pAdapter)
5872 {
5873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005874 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 return -ENODEV;
5876 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005877
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305878 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5879 TRACE_CODE_HDD_CFG80211_STOP_AP,
5880 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5882 status = wlan_hdd_validate_context(pHddCtx);
5883
5884 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005885 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5887 "%s: HDD context is not valid", __func__);
5888 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005889 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005890
5891 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5892 if (NULL == staAdapter)
5893 {
5894 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5895 if (NULL == staAdapter)
5896 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5898 "%s: HDD adapter context for STA/P2P-CLI is Null",
5899 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005900 }
5901 }
5902
5903 pScanInfo = &pHddCtx->scan_info;
5904
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305905 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5906 __func__, hdd_device_modetoString(pAdapter->device_mode),
5907 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005908
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305909 ret = wlan_hdd_scan_abort(pAdapter);
5910
Girish Gowli4bf7a632014-06-12 13:42:11 +05305911 if (ret < 0)
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 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305915
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305916 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005917 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5919 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005920
Jeff Johnsone7245742012-09-05 17:12:55 -07005921 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305922 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005923 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305924 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005925 }
5926
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305927 hdd_hostapd_stop(dev);
5928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 )
5932 {
5933 beacon_data_t *old;
5934
5935 old = pAdapter->sessionCtx.ap.beacon;
5936
5937 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305938 {
5939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5940 FL("session(%d) beacon data points to NULL"),
5941 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005944
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005946
5947 mutex_lock(&pHddCtx->sap_lock);
5948 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5949 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005950 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 {
5952 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5953
5954 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5955
5956 if (!VOS_IS_STATUS_SUCCESS(status))
5957 {
5958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005959 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305961 }
5962 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
5964 }
5965 mutex_unlock(&pHddCtx->sap_lock);
5966
5967 if(status != VOS_STATUS_SUCCESS)
5968 {
5969 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005970 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 return -EINVAL;
5972 }
5973
Jeff Johnson4416a782013-03-25 14:17:50 -07005974 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
5976 ==eHAL_STATUS_FAILURE)
5977 {
5978 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005979 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 }
5981
Jeff Johnson4416a782013-03-25 14:17:50 -07005982 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5984 eANI_BOOLEAN_FALSE) )
5985 {
5986 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005987 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 }
5989
5990 // Reset WNI_CFG_PROBE_RSP Flags
5991 wlan_hdd_reset_prob_rspies(pAdapter);
5992
5993 pAdapter->sessionCtx.ap.beacon = NULL;
5994 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005995#ifdef WLAN_FEATURE_P2P_DEBUG
5996 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
5997 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
5998 {
5999 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6000 "GO got removed");
6001 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6002 }
6003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 }
6005 EXIT();
6006 return status;
6007}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006008
6009#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6010
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306011static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6012 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006013 struct cfg80211_ap_settings *params)
6014{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306015 hdd_adapter_t *pAdapter;
6016 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306017 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006018
6019 ENTER();
6020
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306021 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006022 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306024 "%s: Device is Null", __func__);
6025 return -ENODEV;
6026 }
6027
6028 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6029 if (NULL == pAdapter)
6030 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306032 "%s: HDD adapter is Null", __func__);
6033 return -ENODEV;
6034 }
6035
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6037 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6038 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306039 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6040 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306042 "%s: HDD adapter magic is invalid", __func__);
6043 return -ENODEV;
6044 }
6045
6046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306047 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306048
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306049 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306050 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6052 "%s: HDD context is not valid", __func__);
6053 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306054 }
6055
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306056 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6057 __func__, hdd_device_modetoString(pAdapter->device_mode),
6058 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306059
6060 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006061 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006062 )
6063 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306064 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006065
6066 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306067
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006068 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306069 {
6070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6071 FL("already beacon info added to session(%d)"),
6072 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006073 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306074 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006075
6076 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6077
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306078 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006079 {
6080 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306081 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006082 return -EINVAL;
6083 }
6084 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006085#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006086 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6087#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6088 params->channel, params->channel_type);
6089#else
6090 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6091#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006092#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006093 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6094 params->ssid_len, params->hidden_ssid);
6095 }
6096
6097 EXIT();
6098 return status;
6099}
6100
6101
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306102static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006103 struct net_device *dev,
6104 struct cfg80211_beacon_data *params)
6105{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306107 hdd_context_t *pHddCtx;
6108 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006109
6110 ENTER();
6111
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6113 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6114 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006115 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006116 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306117
6118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6119 status = wlan_hdd_validate_context(pHddCtx);
6120
6121 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6124 "%s: HDD context is not valid", __func__);
6125 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006126 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006127
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006129 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306130 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006131 {
6132 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306133
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006134 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306135
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006136 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306137 {
6138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6139 FL("session(%d) beacon data points to NULL"),
6140 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006141 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306142 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006143
6144 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6145
6146 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306147 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006148 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006149 return -EINVAL;
6150 }
6151
6152 pAdapter->sessionCtx.ap.beacon = new;
6153
6154 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6155 }
6156
6157 EXIT();
6158 return status;
6159}
6160
6161#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6162
Jeff Johnson295189b2012-06-20 16:38:30 -07006163
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306164static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 struct net_device *dev,
6166 struct bss_parameters *params)
6167{
6168 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6169
6170 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6173 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6174 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6176 __func__, hdd_device_modetoString(pAdapter->device_mode),
6177 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006178
6179 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 {
6183 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6184 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306185 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 {
6187 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306188 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 }
6190
6191 EXIT();
6192 return 0;
6193}
6194
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306195static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6196 struct net_device *dev,
6197 struct bss_parameters *params)
6198{
6199 int ret;
6200
6201 vos_ssr_protect(__func__);
6202 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6203 vos_ssr_unprotect(__func__);
6204
6205 return ret;
6206}
Kiet Lam10841362013-11-01 11:36:50 +05306207/* FUNCTION: wlan_hdd_change_country_code_cd
6208* to wait for contry code completion
6209*/
6210void* wlan_hdd_change_country_code_cb(void *pAdapter)
6211{
6212 hdd_adapter_t *call_back_pAdapter = pAdapter;
6213 complete(&call_back_pAdapter->change_country_code);
6214 return NULL;
6215}
6216
Jeff Johnson295189b2012-06-20 16:38:30 -07006217/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306218 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6220 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306221int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 struct net_device *ndev,
6223 enum nl80211_iftype type,
6224 u32 *flags,
6225 struct vif_params *params
6226 )
6227{
6228 struct wireless_dev *wdev;
6229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006230 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006231 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 tCsrRoamProfile *pRoamProfile = NULL;
6233 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306234 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006235 eMib_dot11DesiredBssType connectedBssType;
6236 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306237 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006238
6239 ENTER();
6240
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306241 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006242 {
6243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6244 "%s: Adapter context is null", __func__);
6245 return VOS_STATUS_E_FAILURE;
6246 }
6247
6248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6249 if (!pHddCtx)
6250 {
6251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6252 "%s: HDD context is null", __func__);
6253 return VOS_STATUS_E_FAILURE;
6254 }
6255
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306256 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6257 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6258 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306259 status = wlan_hdd_validate_context(pHddCtx);
6260
6261 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6264 "%s: HDD context is not valid", __func__);
6265 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006266 }
6267
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6269 __func__, hdd_device_modetoString(pAdapter->device_mode),
6270 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006271
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306272 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 wdev = ndev->ieee80211_ptr;
6274
6275#ifdef WLAN_BTAMP_FEATURE
6276 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6277 (NL80211_IFTYPE_ADHOC == type)||
6278 (NL80211_IFTYPE_AP == type)||
6279 (NL80211_IFTYPE_P2P_GO == type))
6280 {
6281 pHddCtx->isAmpAllowed = VOS_FALSE;
6282 // stop AMP traffic
6283 status = WLANBAP_StopAmp();
6284 if(VOS_STATUS_SUCCESS != status )
6285 {
6286 pHddCtx->isAmpAllowed = VOS_TRUE;
6287 hddLog(VOS_TRACE_LEVEL_FATAL,
6288 "%s: Failed to stop AMP", __func__);
6289 return -EINVAL;
6290 }
6291 }
6292#endif //WLAN_BTAMP_FEATURE
6293 /* Reset the current device mode bit mask*/
6294 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6295
6296 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006298 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 )
6300 {
6301 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006302 if (!pWextState)
6303 {
6304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6305 "%s: pWextState is null", __func__);
6306 return VOS_STATUS_E_FAILURE;
6307 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 pRoamProfile = &pWextState->roamProfile;
6309 LastBSSType = pRoamProfile->BSSType;
6310
6311 switch (type)
6312 {
6313 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 hddLog(VOS_TRACE_LEVEL_INFO,
6316 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6317 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006318#ifdef WLAN_FEATURE_11AC
6319 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6320 {
6321 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6322 }
6323#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006325 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006327 //Check for sub-string p2p to confirm its a p2p interface
6328 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306329 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006330 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6331 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6332 }
6333 else
6334 {
6335 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006337 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306338#ifdef FEATURE_WLAN_TDLS
6339 /* The open adapter for the p2p shall skip initializations in
6340 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6341 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6342 * tdls_init when the change_iface sets the device mode to
6343 * WLAN_HDD_P2P_CLIENT.
6344 */
6345
6346 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6347 {
6348 if (0 != wlan_hdd_tdls_init (pAdapter))
6349 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306350 hddLog(VOS_TRACE_LEVEL_ERROR,
6351 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306352 return -EINVAL;
6353 }
6354 }
6355#endif
6356
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 break;
6358 case NL80211_IFTYPE_ADHOC:
6359 hddLog(VOS_TRACE_LEVEL_INFO,
6360 "%s: setting interface Type to ADHOC", __func__);
6361 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6362 pRoamProfile->phyMode =
6363 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006364 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 wdev->iftype = type;
6366 break;
6367
6368 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 {
6371 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6372 "%s: setting interface Type to %s", __func__,
6373 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6374
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006375 //Cancel any remain on channel for GO mode
6376 if (NL80211_IFTYPE_P2P_GO == type)
6377 {
6378 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6379 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006380 if (NL80211_IFTYPE_AP == type)
6381 {
6382 /* As Loading WLAN Driver one interface being created for p2p device
6383 * address. This will take one HW STA and the max number of clients
6384 * that can connect to softAP will be reduced by one. so while changing
6385 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6386 * interface as it is not required in SoftAP mode.
6387 */
6388
6389 // Get P2P Adapter
6390 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6391
6392 if (pP2pAdapter)
6393 {
6394 hdd_stop_adapter(pHddCtx, pP2pAdapter);
6395 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6396 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6397 }
6398 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306399 //Disable IMPS & BMPS for SAP/GO
6400 if(VOS_STATUS_E_FAILURE ==
6401 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6402 {
6403 //Fail to Exit BMPS
6404 VOS_ASSERT(0);
6405 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306406#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006407
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306408 /* A Mutex Lock is introduced while changing the mode to
6409 * protect the concurrent access for the Adapters by TDLS
6410 * module.
6411 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306412 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 //De-init the adapter.
6415 hdd_stop_adapter( pHddCtx, pAdapter );
6416 hdd_deinit_adapter( pHddCtx, pAdapter );
6417 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6419 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306420#ifdef FEATURE_WLAN_TDLS
6421 mutex_unlock(&pHddCtx->tdls_lock);
6422#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006423 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6424 (pConfig->apRandomBssidEnabled))
6425 {
6426 /* To meet Android requirements create a randomized
6427 MAC address of the form 02:1A:11:Fx:xx:xx */
6428 get_random_bytes(&ndev->dev_addr[3], 3);
6429 ndev->dev_addr[0] = 0x02;
6430 ndev->dev_addr[1] = 0x1A;
6431 ndev->dev_addr[2] = 0x11;
6432 ndev->dev_addr[3] |= 0xF0;
6433 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6434 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006435 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6436 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006437 }
6438
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 hdd_set_ap_ops( pAdapter->dev );
6440
Kiet Lam10841362013-11-01 11:36:50 +05306441 /* This is for only SAP mode where users can
6442 * control country through ini.
6443 * P2P GO follows station country code
6444 * acquired during the STA scanning. */
6445 if((NL80211_IFTYPE_AP == type) &&
6446 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6447 {
6448 int status = 0;
6449 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6450 "%s: setting country code from INI ", __func__);
6451 init_completion(&pAdapter->change_country_code);
6452 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6453 (void *)(tSmeChangeCountryCallback)
6454 wlan_hdd_change_country_code_cb,
6455 pConfig->apCntryCode, pAdapter,
6456 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306457 eSIR_FALSE,
6458 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306459 if (eHAL_STATUS_SUCCESS == status)
6460 {
6461 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306462 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306463 &pAdapter->change_country_code,
6464 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306465 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306466 {
6467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306468 FL("SME Timed out while setting country code %ld"),
6469 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006470
6471 if (pHddCtx->isLogpInProgress)
6472 {
6473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6474 "%s: LOGP in Progress. Ignore!!!", __func__);
6475 return -EAGAIN;
6476 }
Kiet Lam10841362013-11-01 11:36:50 +05306477 }
6478 }
6479 else
6480 {
6481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006482 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306483 return -EINVAL;
6484 }
6485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 status = hdd_init_ap_mode(pAdapter);
6487 if(status != VOS_STATUS_SUCCESS)
6488 {
6489 hddLog(VOS_TRACE_LEVEL_FATAL,
6490 "%s: Error initializing the ap mode", __func__);
6491 return -EINVAL;
6492 }
6493 hdd_set_conparam(1);
6494
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 /*interface type changed update in wiphy structure*/
6496 if(wdev)
6497 {
6498 wdev->iftype = type;
6499 pHddCtx->change_iface = type;
6500 }
6501 else
6502 {
6503 hddLog(VOS_TRACE_LEVEL_ERROR,
6504 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6505 return -EINVAL;
6506 }
6507 goto done;
6508 }
6509
6510 default:
6511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6512 __func__);
6513 return -EOPNOTSUPP;
6514 }
6515 }
6516 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 )
6519 {
6520 switch(type)
6521 {
6522 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006524 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306525#ifdef FEATURE_WLAN_TDLS
6526
6527 /* A Mutex Lock is introduced while changing the mode to
6528 * protect the concurrent access for the Adapters by TDLS
6529 * module.
6530 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306531 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306532#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07006533 hdd_stop_adapter( pHddCtx, pAdapter );
6534 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006536 //Check for sub-string p2p to confirm its a p2p interface
6537 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006538 {
6539 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6540 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6541 }
6542 else
6543 {
6544 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 hdd_set_conparam(0);
6548 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6550 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306551#ifdef FEATURE_WLAN_TDLS
6552 mutex_unlock(&pHddCtx->tdls_lock);
6553#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306554 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 if( VOS_STATUS_SUCCESS != status )
6556 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006557 /* In case of JB, for P2P-GO, only change interface will be called,
6558 * This is the right place to enable back bmps_imps()
6559 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306560 if (pHddCtx->hdd_wlan_suspended)
6561 {
6562 hdd_set_pwrparams(pHddCtx);
6563 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006564 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 goto done;
6566 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6570 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 goto done;
6572 default:
6573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6574 __func__);
6575 return -EOPNOTSUPP;
6576
6577 }
6578
6579 }
6580 else
6581 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306582 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6583 __func__, hdd_device_modetoString(pAdapter->device_mode),
6584 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 return -EOPNOTSUPP;
6586 }
6587
6588
6589 if(pRoamProfile)
6590 {
6591 if ( LastBSSType != pRoamProfile->BSSType )
6592 {
6593 /*interface type changed update in wiphy structure*/
6594 wdev->iftype = type;
6595
6596 /*the BSS mode changed, We need to issue disconnect
6597 if connected or in IBSS disconnect state*/
6598 if ( hdd_connGetConnectedBssType(
6599 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6600 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6601 {
6602 /*need to issue a disconnect to CSR.*/
6603 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6604 if( eHAL_STATUS_SUCCESS ==
6605 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6606 pAdapter->sessionId,
6607 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6608 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306609 ret = wait_for_completion_interruptible_timeout(
6610 &pAdapter->disconnect_comp_var,
6611 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6612 if (ret <= 0)
6613 {
6614 hddLog(VOS_TRACE_LEVEL_ERROR,
6615 FL("wait on disconnect_comp_var failed %ld"), ret);
6616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 }
6618 }
6619 }
6620 }
6621
6622done:
6623 /*set bitmask based on updated value*/
6624 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006625
6626 /* Only STA mode support TM now
6627 * all other mode, TM feature should be disabled */
6628 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6629 (~VOS_STA & pHddCtx->concurrency_mode) )
6630 {
6631 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6632 }
6633
Jeff Johnson295189b2012-06-20 16:38:30 -07006634#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306635 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6637 {
6638 //we are ok to do AMP
6639 pHddCtx->isAmpAllowed = VOS_TRUE;
6640 }
6641#endif //WLAN_BTAMP_FEATURE
6642 EXIT();
6643 return 0;
6644}
6645
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306646/*
6647 * FUNCTION: wlan_hdd_cfg80211_change_iface
6648 * wrapper function to protect the actual implementation from SSR.
6649 */
6650int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6651 struct net_device *ndev,
6652 enum nl80211_iftype type,
6653 u32 *flags,
6654 struct vif_params *params
6655 )
6656{
6657 int ret;
6658
6659 vos_ssr_protect(__func__);
6660 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6661 vos_ssr_unprotect(__func__);
6662
6663 return ret;
6664}
6665
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006666#ifdef FEATURE_WLAN_TDLS
6667static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6668 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6669{
6670 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6672 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006673 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306674 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306675 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006676
6677 ENTER();
6678
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306679 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006680 {
6681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6682 "Invalid arguments");
6683 return -EINVAL;
6684 }
Hoonki Lee27511902013-03-14 18:19:06 -07006685
6686 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6687 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6688 {
6689 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6690 "%s: TDLS mode is disabled OR not enabled in FW."
6691 MAC_ADDRESS_STR " Request declined.",
6692 __func__, MAC_ADDR_ARRAY(mac));
6693 return -ENOTSUPP;
6694 }
6695
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006696 if (pHddCtx->isLogpInProgress)
6697 {
6698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6699 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006700 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006701 return -EBUSY;
6702 }
6703
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306704 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006705
6706 if ( NULL == pTdlsPeer ) {
6707 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6708 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6709 __func__, MAC_ADDR_ARRAY(mac), update);
6710 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006711 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006712
6713 /* in add station, we accept existing valid staId if there is */
6714 if ((0 == update) &&
6715 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6716 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006717 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006718 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006719 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006720 " link_status %d. staId %d. add station ignored.",
6721 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6722 return 0;
6723 }
6724 /* in change station, we accept only when staId is valid */
6725 if ((1 == update) &&
6726 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6727 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6728 {
6729 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6730 "%s: " MAC_ADDRESS_STR
6731 " link status %d. staId %d. change station %s.",
6732 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6733 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6734 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006735 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006736
6737 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306738 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006739 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6741 "%s: " MAC_ADDRESS_STR
6742 " TDLS setup is ongoing. Request declined.",
6743 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006744 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006745 }
6746
6747 /* first to check if we reached to maximum supported TDLS peer.
6748 TODO: for now, return -EPERM looks working fine,
6749 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306750 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6751 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006752 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6754 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306755 " TDLS Max peer already connected. Request declined."
6756 " Num of peers (%d), Max allowed (%d).",
6757 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6758 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006759 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006760 }
6761 else
6762 {
6763 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306764 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006765 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006766 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6768 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6769 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006770 return -EPERM;
6771 }
6772 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006773 if (0 == update)
6774 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006775
Jeff Johnsond75fe012013-04-06 10:53:06 -07006776 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306777 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006778 {
6779 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6780 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006781 if(StaParams->htcap_present)
6782 {
6783 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6784 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6785 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6786 "ht_capa->extended_capabilities: %0x",
6787 StaParams->HTCap.extendedHtCapInfo);
6788 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006789 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6790 "params->capability: %0x",StaParams->capability);
6791 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006792 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006793 if(StaParams->vhtcap_present)
6794 {
6795 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6796 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6797 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6798 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6799 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006800 {
6801 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006803 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6804 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6805 "[%d]: %x ", i, StaParams->supported_rates[i]);
6806 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006807 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306808 else if ((1 == update) && (NULL == StaParams))
6809 {
6810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6811 "%s : update is true, but staParams is NULL. Error!", __func__);
6812 return -EPERM;
6813 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006814
6815 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6816
6817 if (!update)
6818 {
6819 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6820 pAdapter->sessionId, mac);
6821 }
6822 else
6823 {
6824 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6825 pAdapter->sessionId, mac, StaParams);
6826 }
6827
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306828 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006829 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6830
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306831 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006832 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306834 "%s: timeout waiting for tdls add station indication %ld",
6835 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006836 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006837 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306838
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006839 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6840 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006842 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006843 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006844 }
6845
6846 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006847
6848error:
6849 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6850 return -EPERM;
6851
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006852}
6853#endif
6854
Jeff Johnson295189b2012-06-20 16:38:30 -07006855static int wlan_hdd_change_station(struct wiphy *wiphy,
6856 struct net_device *dev,
6857 u8 *mac,
6858 struct station_parameters *params)
6859{
6860 VOS_STATUS status = VOS_STATUS_SUCCESS;
6861 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306862 hdd_context_t *pHddCtx;
6863 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006865#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006866 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006867 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306868 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006869#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006870 ENTER();
6871
Gopichand Nakkala29149562013-05-10 21:43:41 +05306872 if ((NULL == pAdapter))
6873 {
6874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6875 "invalid adapter ");
6876 return -EINVAL;
6877 }
6878
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6880 TRACE_CODE_HDD_CHANGE_STATION,
6881 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306882 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6883 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6884
6885 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6886 {
6887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6888 "invalid HDD state or HDD station context");
6889 return -EINVAL;
6890 }
6891
6892 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006893 {
6894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6895 "%s:LOGP in Progress. Ignore!!!", __func__);
6896 return -EAGAIN;
6897 }
6898
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6900
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006901 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6902 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006904 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 WLANTL_STA_AUTHENTICATED);
6908
Gopichand Nakkala29149562013-05-10 21:43:41 +05306909 if (status != VOS_STATUS_SUCCESS)
6910 {
6911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6912 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6913 return -EINVAL;
6914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 }
6916 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006917 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6918 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306919#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006920 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6921 StaParams.capability = params->capability;
6922 StaParams.uapsd_queues = params->uapsd_queues;
6923 StaParams.max_sp = params->max_sp;
6924
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306925 /* Convert (first channel , number of channels) tuple to
6926 * the total list of channels. This goes with the assumption
6927 * that if the first channel is < 14, then the next channels
6928 * are an incremental of 1 else an incremental of 4 till the number
6929 * of channels.
6930 */
6931 if (0 != params->supported_channels_len) {
6932 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6933 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6934 {
6935 int wifi_chan_index;
6936 StaParams.supported_channels[j] = params->supported_channels[i];
6937 wifi_chan_index =
6938 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6939 no_of_channels = params->supported_channels[i+1];
6940 for(k=1; k <= no_of_channels; k++)
6941 {
6942 StaParams.supported_channels[j+1] =
6943 StaParams.supported_channels[j] + wifi_chan_index;
6944 j+=1;
6945 }
6946 }
6947 StaParams.supported_channels_len = j;
6948 }
6949 vos_mem_copy(StaParams.supported_oper_classes,
6950 params->supported_oper_classes,
6951 params->supported_oper_classes_len);
6952 StaParams.supported_oper_classes_len =
6953 params->supported_oper_classes_len;
6954
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006955 if (0 != params->ext_capab_len)
6956 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
6957 sizeof(StaParams.extn_capability));
6958
6959 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006960 {
6961 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006962 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006963 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006964
6965 StaParams.supported_rates_len = params->supported_rates_len;
6966
6967 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
6968 * The supported_rates array , for all the structures propogating till Add Sta
6969 * to the firmware has to be modified , if the supplicant (ieee80211) is
6970 * modified to send more rates.
6971 */
6972
6973 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
6974 */
6975 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
6976 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
6977
6978 if (0 != StaParams.supported_rates_len) {
6979 int i = 0;
6980 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
6981 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006983 "Supported Rates with Length %d", StaParams.supported_rates_len);
6984 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006986 "[%d]: %0x", i, StaParams.supported_rates[i]);
6987 }
6988
6989 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07006990 {
6991 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006992 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07006993 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006994
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006995 if (0 != params->ext_capab_len ) {
6996 /*Define A Macro : TODO Sunil*/
6997 if ((1<<4) & StaParams.extn_capability[3]) {
6998 isBufSta = 1;
6999 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307000 /* TDLS Channel Switching Support */
7001 if ((1<<6) & StaParams.extn_capability[3]) {
7002 isOffChannelSupported = 1;
7003 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007004 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307005 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7006 &StaParams, isBufSta,
7007 isOffChannelSupported);
7008
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307009 if (VOS_STATUS_SUCCESS != status) {
7010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7011 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7012 return -EINVAL;
7013 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007014 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7015
7016 if (VOS_STATUS_SUCCESS != status) {
7017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7018 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7019 return -EINVAL;
7020 }
7021 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007022#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307023 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007024 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 return status;
7026}
7027
7028/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307029 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 * This function is used to initialize the key information
7031 */
7032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307033static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 struct net_device *ndev,
7035 u8 key_index, bool pairwise,
7036 const u8 *mac_addr,
7037 struct key_params *params
7038 )
7039#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307040static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 struct net_device *ndev,
7042 u8 key_index, const u8 *mac_addr,
7043 struct key_params *params
7044 )
7045#endif
7046{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007047 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 tCsrRoamSetKey setKey;
7049 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307050 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007051 v_U32_t roamId= 0xFF;
7052 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 hdd_hostapd_state_t *pHostapdState;
7054 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007055 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307056 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007057
7058 ENTER();
7059
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7061 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7062 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307063 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7064 status = wlan_hdd_validate_context(pHddCtx);
7065
7066 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007067 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7069 "%s: HDD context is not valid", __func__);
7070 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007071 }
7072
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7074 __func__, hdd_device_modetoString(pAdapter->device_mode),
7075 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007076
7077 if (CSR_MAX_NUM_KEY <= key_index)
7078 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 key_index);
7081
7082 return -EINVAL;
7083 }
7084
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007085 if (CSR_MAX_KEY_LEN < params->key_len)
7086 {
7087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7088 params->key_len);
7089
7090 return -EINVAL;
7091 }
7092
7093 hddLog(VOS_TRACE_LEVEL_INFO,
7094 "%s: called with key index = %d & key length %d",
7095 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007096
7097 /*extract key idx, key len and key*/
7098 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7099 setKey.keyId = key_index;
7100 setKey.keyLength = params->key_len;
7101 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7102
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007103 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 {
7105 case WLAN_CIPHER_SUITE_WEP40:
7106 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7107 break;
7108
7109 case WLAN_CIPHER_SUITE_WEP104:
7110 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7111 break;
7112
7113 case WLAN_CIPHER_SUITE_TKIP:
7114 {
7115 u8 *pKey = &setKey.Key[0];
7116 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7117
7118 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7119
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007120 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007121
7122 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007123 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 |--------------|----------|----------|
7125 <---16bytes---><--8bytes--><--8bytes-->
7126
7127 */
7128 /*Sme expects the 32 bytes key to be in the below order
7129
7130 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007131 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 |--------------|----------|----------|
7133 <---16bytes---><--8bytes--><--8bytes-->
7134 */
7135 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007136 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007137
7138 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007139 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007140
7141 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007142 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144
7145 break;
7146 }
7147
7148 case WLAN_CIPHER_SUITE_CCMP:
7149 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7150 break;
7151
7152#ifdef FEATURE_WLAN_WAPI
7153 case WLAN_CIPHER_SUITE_SMS4:
7154 {
7155 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7156 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7157 params->key, params->key_len);
7158 return 0;
7159 }
7160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007161
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007162#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 case WLAN_CIPHER_SUITE_KRK:
7164 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7165 break;
7166#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007167
7168#ifdef WLAN_FEATURE_11W
7169 case WLAN_CIPHER_SUITE_AES_CMAC:
7170 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007171 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007172#endif
7173
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 __func__, params->cipher);
7177 return -EOPNOTSUPP;
7178 }
7179
7180 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7181 __func__, setKey.encType);
7182
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007183 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7185 (!pairwise)
7186#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007187 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007188#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007189 )
7190 {
7191 /* set group key*/
7192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7193 "%s- %d: setting Broadcast key",
7194 __func__, __LINE__);
7195 setKey.keyDirection = eSIR_RX_ONLY;
7196 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7197 }
7198 else
7199 {
7200 /* set pairwise key*/
7201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7202 "%s- %d: setting pairwise key",
7203 __func__, __LINE__);
7204 setKey.keyDirection = eSIR_TX_RX;
7205 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7206 }
7207 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7208 {
7209 setKey.keyDirection = eSIR_TX_RX;
7210 /*Set the group key*/
7211 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7212 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007213
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007214 if ( 0 != status )
7215 {
7216 hddLog(VOS_TRACE_LEVEL_ERROR,
7217 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7218 return -EINVAL;
7219 }
7220 /*Save the keys here and call sme_RoamSetKey for setting
7221 the PTK after peer joins the IBSS network*/
7222 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7223 &setKey, sizeof(tCsrRoamSetKey));
7224 return status;
7225 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307226 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7227 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7228 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007230 if( pHostapdState->bssState == BSS_START )
7231 {
c_hpothu7c55da62014-01-23 18:34:02 +05307232 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7233 vos_status = wlan_hdd_check_ula_done(pAdapter);
7234
7235 if ( vos_status != VOS_STATUS_SUCCESS )
7236 {
7237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7238 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7239 __LINE__, vos_status );
7240
7241 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7242
7243 return -EINVAL;
7244 }
7245
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7247
7248 if ( status != eHAL_STATUS_SUCCESS )
7249 {
7250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7251 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7252 __LINE__, status );
7253 }
7254 }
7255
7256 /* Saving WEP keys */
7257 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7258 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7259 {
7260 //Save the wep key in ap context. Issue setkey after the BSS is started.
7261 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7262 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7263 }
7264 else
7265 {
7266 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007267 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7269 }
7270 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007271 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7272 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007273 {
7274 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7275 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7276
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7278 if (!pairwise)
7279#else
7280 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7281#endif
7282 {
7283 /* set group key*/
7284 if (pHddStaCtx->roam_info.deferKeyComplete)
7285 {
7286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7287 "%s- %d: Perform Set key Complete",
7288 __func__, __LINE__);
7289 hdd_PerformRoamSetKeyComplete(pAdapter);
7290 }
7291 }
7292
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7294
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007295 pWextState->roamProfile.Keys.defaultIndex = key_index;
7296
7297
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007298 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 params->key, params->key_len);
7300
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307301
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307304 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307306 __func__, setKey.peerMac[0], setKey.peerMac[1],
7307 setKey.peerMac[2], setKey.peerMac[3],
7308 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 setKey.keyDirection);
7310
7311 vos_status = wlan_hdd_check_ula_done(pAdapter);
7312
7313 if ( vos_status != VOS_STATUS_SUCCESS )
7314 {
7315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7317 __LINE__, vos_status );
7318
7319 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7320
7321 return -EINVAL;
7322
7323 }
7324
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007325#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307326 /* The supplicant may attempt to set the PTK once pre-authentication
7327 is done. Save the key in the UMAC and include it in the ADD BSS
7328 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007329 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307330 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007331 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307332 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7333 "%s: Update PreAuth Key success", __func__);
7334 return 0;
7335 }
7336 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7337 {
7338 hddLog(VOS_TRACE_LEVEL_ERROR,
7339 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307340 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007341 }
7342#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007343
7344 /* issue set key request to SME*/
7345 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7346 pAdapter->sessionId, &setKey, &roamId );
7347
7348 if ( 0 != status )
7349 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307350 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7352 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7353 return -EINVAL;
7354 }
7355
7356
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307357 /* in case of IBSS as there was no information available about WEP keys during
7358 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307360 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7361 !( ( IW_AUTH_KEY_MGMT_802_1X
7362 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007363 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7364 )
7365 &&
7366 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7367 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7368 )
7369 )
7370 {
7371 setKey.keyDirection = eSIR_RX_ONLY;
7372 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7373
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307374 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307376 __func__, setKey.peerMac[0], setKey.peerMac[1],
7377 setKey.peerMac[2], setKey.peerMac[3],
7378 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 setKey.keyDirection);
7380
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307381 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 pAdapter->sessionId, &setKey, &roamId );
7383
7384 if ( 0 != status )
7385 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307386 hddLog(VOS_TRACE_LEVEL_ERROR,
7387 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 __func__, status);
7389 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7390 return -EINVAL;
7391 }
7392 }
7393 }
7394
7395 return 0;
7396}
7397
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7399static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7400 struct net_device *ndev,
7401 u8 key_index, bool pairwise,
7402 const u8 *mac_addr,
7403 struct key_params *params
7404 )
7405#else
7406static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7407 struct net_device *ndev,
7408 u8 key_index, const u8 *mac_addr,
7409 struct key_params *params
7410 )
7411#endif
7412{
7413 int ret;
7414 vos_ssr_protect(__func__);
7415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7416 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7417 mac_addr, params);
7418#else
7419 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7420 params);
7421#endif
7422 vos_ssr_unprotect(__func__);
7423
7424 return ret;
7425}
7426
Jeff Johnson295189b2012-06-20 16:38:30 -07007427/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307428 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 * This function is used to get the key information
7430 */
7431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307432static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307433 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307435 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 const u8 *mac_addr, void *cookie,
7437 void (*callback)(void *cookie, struct key_params*)
7438 )
7439#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307440static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307441 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 struct net_device *ndev,
7443 u8 key_index, const u8 *mac_addr, void *cookie,
7444 void (*callback)(void *cookie, struct key_params*)
7445 )
7446#endif
7447{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7450 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
7451 struct key_params params;
7452
7453 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307454
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7456 __func__, hdd_device_modetoString(pAdapter->device_mode),
7457 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307458
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 memset(&params, 0, sizeof(params));
7460
7461 if (CSR_MAX_NUM_KEY <= key_index)
7462 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007466
7467 switch(pRoamProfile->EncryptionType.encryptionType[0])
7468 {
7469 case eCSR_ENCRYPT_TYPE_NONE:
7470 params.cipher = IW_AUTH_CIPHER_NONE;
7471 break;
7472
7473 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7474 case eCSR_ENCRYPT_TYPE_WEP40:
7475 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7476 break;
7477
7478 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7479 case eCSR_ENCRYPT_TYPE_WEP104:
7480 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7481 break;
7482
7483 case eCSR_ENCRYPT_TYPE_TKIP:
7484 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7485 break;
7486
7487 case eCSR_ENCRYPT_TYPE_AES:
7488 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7489 break;
7490
7491 default:
7492 params.cipher = IW_AUTH_CIPHER_NONE;
7493 break;
7494 }
7495
c_hpothuaaf19692014-05-17 17:01:48 +05307496 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7497 TRACE_CODE_HDD_CFG80211_GET_KEY,
7498 pAdapter->sessionId, params.cipher));
7499
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7501 params.seq_len = 0;
7502 params.seq = NULL;
7503 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7504 callback(cookie, &params);
7505 return 0;
7506}
7507
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307508#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7509static int wlan_hdd_cfg80211_get_key(
7510 struct wiphy *wiphy,
7511 struct net_device *ndev,
7512 u8 key_index, bool pairwise,
7513 const u8 *mac_addr, void *cookie,
7514 void (*callback)(void *cookie, struct key_params*)
7515 )
7516#else
7517static int wlan_hdd_cfg80211_get_key(
7518 struct wiphy *wiphy,
7519 struct net_device *ndev,
7520 u8 key_index, const u8 *mac_addr, void *cookie,
7521 void (*callback)(void *cookie, struct key_params*)
7522 )
7523#endif
7524{
7525 int ret;
7526
7527 vos_ssr_protect(__func__);
7528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7529 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7530 mac_addr, cookie, callback);
7531#else
7532 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7533 callback);
7534#endif
7535 vos_ssr_unprotect(__func__);
7536
7537 return ret;
7538}
7539
Jeff Johnson295189b2012-06-20 16:38:30 -07007540/*
7541 * FUNCTION: wlan_hdd_cfg80211_del_key
7542 * This function is used to delete the key information
7543 */
7544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307545static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307547 u8 key_index,
7548 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 const u8 *mac_addr
7550 )
7551#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307552static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 struct net_device *ndev,
7554 u8 key_index,
7555 const u8 *mac_addr
7556 )
7557#endif
7558{
7559 int status = 0;
7560
7561 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 //it is observed that this is invalidating peer
7564 //key index whenever re-key is done. This is affecting data link.
7565 //It should be ok to ignore del_key.
7566#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7568 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007569 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7570 tCsrRoamSetKey setKey;
7571 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307572
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 ENTER();
7574
7575 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7576 __func__,pAdapter->device_mode);
7577
7578 if (CSR_MAX_NUM_KEY <= key_index)
7579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 key_index);
7582
7583 return -EINVAL;
7584 }
7585
7586 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7587 setKey.keyId = key_index;
7588
7589 if (mac_addr)
7590 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7591 else
7592 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7593
7594 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7595
7596 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307598 )
7599 {
7600
7601 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7603 if( pHostapdState->bssState == BSS_START)
7604 {
7605 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307606
Jeff Johnson295189b2012-06-20 16:38:30 -07007607 if ( status != eHAL_STATUS_SUCCESS )
7608 {
7609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7610 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7611 __LINE__, status );
7612 }
7613 }
7614 }
7615 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307616 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 )
7618 {
7619 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7620
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307621 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7622
7623 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307625 __func__, setKey.peerMac[0], setKey.peerMac[1],
7626 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307628 if(pAdapter->sessionCtx.station.conn_info.connState ==
7629 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307631 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307633
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 if ( 0 != status )
7635 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307636 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 "%s: sme_RoamSetKey failure, returned %d",
7638 __func__, status);
7639 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7640 return -EINVAL;
7641 }
7642 }
7643 }
7644#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007645 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 return status;
7647}
7648
7649/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307650 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 * This function is used to set the default tx key index
7652 */
7653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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 bool unicast, bool multicast)
7658#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307659static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 struct net_device *ndev,
7661 u8 key_index)
7662#endif
7663{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307665 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307666 hdd_wext_state_t *pWextState;
7667 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307668 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007669
7670 ENTER();
7671
Gopichand Nakkala29149562013-05-10 21:43:41 +05307672 if ((NULL == pAdapter))
7673 {
7674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7675 "invalid adapter");
7676 return -EINVAL;
7677 }
7678
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307679 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7680 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7681 pAdapter->sessionId, key_index));
7682
Gopichand Nakkala29149562013-05-10 21:43:41 +05307683 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7684 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7685
7686 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7687 {
7688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7689 "invalid Wext state or HDD context");
7690 return -EINVAL;
7691 }
7692
Arif Hussain6d2a3322013-11-17 19:50:10 -08007693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307695
Jeff Johnson295189b2012-06-20 16:38:30 -07007696 if (CSR_MAX_NUM_KEY <= key_index)
7697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 key_index);
7700
7701 return -EINVAL;
7702 }
7703
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307704 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7705 status = wlan_hdd_validate_context(pHddCtx);
7706
7707 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007708 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7710 "%s: HDD context is not valid", __func__);
7711 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007712 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307713
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307716 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307718 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007719 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307720 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007721 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307723 {
7724 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307726
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 tCsrRoamSetKey setKey;
7728 v_U32_t roamId= 0xFF;
7729 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307730
7731 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007732 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 Keys->defaultIndex = (u8)key_index;
7735 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7736 setKey.keyId = key_index;
7737 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307738
7739 vos_mem_copy(&setKey.Key[0],
7740 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307742
Gopichand Nakkala29149562013-05-10 21:43:41 +05307743 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307744
7745 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 &pHddStaCtx->conn_info.bssId[0],
7747 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307748
Gopichand Nakkala29149562013-05-10 21:43:41 +05307749 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7750 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7751 eCSR_ENCRYPT_TYPE_WEP104)
7752 {
7753 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7754 even though ap is configured for WEP-40 encryption. In this canse the key length
7755 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7756 type(104) and switching encryption type to 40*/
7757 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7758 eCSR_ENCRYPT_TYPE_WEP40;
7759 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7760 eCSR_ENCRYPT_TYPE_WEP40;
7761 }
7762
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307765
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307767 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307769
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 if ( 0 != status )
7771 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307772 hddLog(VOS_TRACE_LEVEL_ERROR,
7773 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 status);
7775 return -EINVAL;
7776 }
7777 }
7778 }
7779
7780 /* In SoftAp mode setting key direction for default mode */
7781 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7782 {
7783 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7784 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7785 (eCSR_ENCRYPT_TYPE_AES !=
7786 pWextState->roamProfile.EncryptionType.encryptionType[0])
7787 )
7788 {
7789 /* Saving key direction for default key index to TX default */
7790 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7791 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7792 }
7793 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 return status;
7796}
7797
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7799static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7800 struct net_device *ndev,
7801 u8 key_index,
7802 bool unicast, bool multicast)
7803#else
7804static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7805 struct net_device *ndev,
7806 u8 key_index)
7807#endif
7808{
7809 int ret;
7810 vos_ssr_protect(__func__);
7811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7812 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7813 multicast);
7814#else
7815 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7816#endif
7817 vos_ssr_unprotect(__func__);
7818
7819 return ret;
7820}
7821
Jeff Johnson295189b2012-06-20 16:38:30 -07007822/*
7823 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7824 * This function is used to inform the BSS details to nl80211 interface.
7825 */
7826static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7827 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7828{
7829 struct net_device *dev = pAdapter->dev;
7830 struct wireless_dev *wdev = dev->ieee80211_ptr;
7831 struct wiphy *wiphy = wdev->wiphy;
7832 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7833 int chan_no;
7834 int ie_length;
7835 const char *ie;
7836 unsigned int freq;
7837 struct ieee80211_channel *chan;
7838 int rssi = 0;
7839 struct cfg80211_bss *bss = NULL;
7840
7841 ENTER();
7842
7843 if( NULL == pBssDesc )
7844 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007845 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 return bss;
7847 }
7848
7849 chan_no = pBssDesc->channelId;
7850 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7851 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7852
7853 if( NULL == ie )
7854 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007855 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007856 return bss;
7857 }
7858
7859#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7860 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7861 {
7862 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7863 }
7864 else
7865 {
7866 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7867 }
7868#else
7869 freq = ieee80211_channel_to_frequency(chan_no);
7870#endif
7871
7872 chan = __ieee80211_get_channel(wiphy, freq);
7873
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307874 if (!chan) {
7875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7876 return NULL;
7877 }
7878
Abhishek Singhaee43942014-06-16 18:55:47 +05307879 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007880
Abhishek Singhaee43942014-06-16 18:55:47 +05307881 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307882 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007883 pBssDesc->capabilityInfo,
7884 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307885 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007886}
7887
7888
7889
7890/*
7891 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7892 * This function is used to inform the BSS details to nl80211 interface.
7893 */
7894struct cfg80211_bss*
7895wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7896 tSirBssDescription *bss_desc
7897 )
7898{
7899 /*
7900 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7901 already exists in bss data base of cfg80211 for that particular BSS ID.
7902 Using cfg80211_inform_bss_frame to update the bss entry instead of
7903 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7904 now there is no possibility to get the mgmt(probe response) frame from PE,
7905 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7906 cfg80211_inform_bss_frame.
7907 */
7908 struct net_device *dev = pAdapter->dev;
7909 struct wireless_dev *wdev = dev->ieee80211_ptr;
7910 struct wiphy *wiphy = wdev->wiphy;
7911 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007912#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7913 qcom_ie_age *qie_age = NULL;
7914 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7915#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007917#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 const char *ie =
7919 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7920 unsigned int freq;
7921 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307922 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 struct cfg80211_bss *bss_status = NULL;
7924 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7925 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007926 hdd_context_t *pHddCtx;
7927 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007928#ifdef WLAN_OPEN_SOURCE
7929 struct timespec ts;
7930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007931
Wilson Yangf80a0542013-10-07 13:02:37 -07007932 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7933 status = wlan_hdd_validate_context(pHddCtx);
7934
7935 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307936 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007937 {
7938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7939 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7940 return NULL;
7941 }
7942
7943
7944 if (0 != status)
7945 {
7946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7947 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007948 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007949 }
7950
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307951 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007952 if (!mgmt)
7953 {
7954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7955 "%s: memory allocation failed ", __func__);
7956 return NULL;
7957 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007958
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07007960
7961#ifdef WLAN_OPEN_SOURCE
7962 /* Android does not want the timestamp from the frame.
7963 Instead it wants a monotonic increasing value */
7964 get_monotonic_boottime(&ts);
7965 mgmt->u.probe_resp.timestamp =
7966 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
7967#else
7968 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
7970 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07007971
7972#endif
7973
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
7975 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007976
7977#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7978 /* GPS Requirement: need age ie per entry. Using vendor specific. */
7979 /* Assuming this is the last IE, copy at the end */
7980 ie_length -=sizeof(qcom_ie_age);
7981 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
7982 qie_age->element_id = QCOM_VENDOR_IE_ID;
7983 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
7984 qie_age->oui_1 = QCOM_OUI1;
7985 qie_age->oui_2 = QCOM_OUI2;
7986 qie_age->oui_3 = QCOM_OUI3;
7987 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
7988 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
7989#endif
7990
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05307992 if (bss_desc->fProbeRsp)
7993 {
7994 mgmt->frame_control |=
7995 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
7996 }
7997 else
7998 {
7999 mgmt->frame_control |=
8000 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008002
8003#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8006 {
8007 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8008 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8011
8012 {
8013 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8014 }
8015 else
8016 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8018 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 kfree(mgmt);
8020 return NULL;
8021 }
8022#else
8023 freq = ieee80211_channel_to_frequency(chan_no);
8024#endif
8025 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008026 /*when the band is changed on the fly using the GUI, three things are done
8027 * 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)
8028 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8029 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8030 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8031 * and discards the channels correponding to previous band and calls back with zero bss results.
8032 * 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
8033 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8034 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8035 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8036 * So drop the bss and continue to next bss.
8037 */
8038 if(chan == NULL)
8039 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008041 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008042 return NULL;
8043 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308045 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 * */
8047 if (( eConnectionState_Associated ==
8048 pAdapter->sessionCtx.station.conn_info.connState ) &&
8049 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8050 pAdapter->sessionCtx.station.conn_info.bssId,
8051 WNI_CFG_BSSID_LEN)))
8052 {
8053 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8054 rssi = (pAdapter->rssi * 100);
8055 }
8056 else
8057 {
8058 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8059 }
8060
Nirav Shah20ac06f2013-12-12 18:14:06 +05308061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8062 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8063 chan->center_freq, (int)(rssi/100));
8064
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8066 frame_len, rssi, GFP_KERNEL);
8067 kfree(mgmt);
8068 return bss_status;
8069}
8070
8071/*
8072 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8073 * This function is used to update the BSS data base of CFG8011
8074 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308075struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 tCsrRoamInfo *pRoamInfo
8077 )
8078{
8079 tCsrRoamConnectedProfile roamProfile;
8080 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8081 struct cfg80211_bss *bss = NULL;
8082
8083 ENTER();
8084
8085 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8086 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8087
8088 if (NULL != roamProfile.pBssDesc)
8089 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 &roamProfile);
8092
8093 if (NULL == bss)
8094 {
8095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8096 __func__);
8097 }
8098
8099 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8100 }
8101 else
8102 {
8103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8104 __func__);
8105 }
8106 return bss;
8107}
8108
8109/*
8110 * FUNCTION: wlan_hdd_cfg80211_update_bss
8111 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308112static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8113 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308115{
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8117 tCsrScanResultInfo *pScanResult;
8118 eHalStatus status = 0;
8119 tScanResultHandle pResult;
8120 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008121 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008122
8123 ENTER();
8124
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8126 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8127 NO_SESSION, pAdapter->sessionId));
8128
Wilson Yangf80a0542013-10-07 13:02:37 -07008129 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8130
8131 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8134 "%s:LOGP in Progress. Ignore!!!",__func__);
8135 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 }
8137
Wilson Yangf80a0542013-10-07 13:02:37 -07008138
8139 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308140 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008141 {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8144 return VOS_STATUS_E_PERM;
8145 }
8146
8147
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 /*
8149 * start getting scan results and populate cgf80211 BSS database
8150 */
8151 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8152
8153 /* no scan results */
8154 if (NULL == pResult)
8155 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8157 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 return status;
8159 }
8160
8161 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8162
8163 while (pScanResult)
8164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165 /*
8166 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8167 * entry already exists in bss data base of cfg80211 for that
8168 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8169 * bss entry instead of cfg80211_inform_bss, But this call expects
8170 * mgmt packet as input. As of now there is no possibility to get
8171 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 * ieee80211_mgmt(probe response) and passing to c
8173 * fg80211_inform_bss_frame.
8174 * */
8175
8176 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8177 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308178
Jeff Johnson295189b2012-06-20 16:38:30 -07008179
8180 if (NULL == bss_status)
8181 {
8182 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008183 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 }
8185 else
8186 {
Yue Maf49ba872013-08-19 12:04:25 -07008187 cfg80211_put_bss(
8188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8189 wiphy,
8190#endif
8191 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 }
8193
8194 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8195 }
8196
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308197 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008198
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008200}
8201
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008202void
8203hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8204{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308205 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008206 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008207} /****** end hddPrintMacAddr() ******/
8208
8209void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008210hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008211{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008213 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008214 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8215 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8216 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008217} /****** end hddPrintPmkId() ******/
8218
8219//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8220//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8221
8222//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8223//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8224
8225#define dump_bssid(bssid) \
8226 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008227 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8228 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008229 }
8230
8231#define dump_pmkid(pMac, pmkid) \
8232 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008233 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8234 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008235 }
8236
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008237#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008238/*
8239 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8240 * This function is used to notify the supplicant of a new PMKSA candidate.
8241 */
8242int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308243 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008244 int index, bool preauth )
8245{
Jeff Johnsone7245742012-09-05 17:12:55 -07008246#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008247 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008248 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008249
8250 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008251 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008252
8253 if( NULL == pRoamInfo )
8254 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008255 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008256 return -EINVAL;
8257 }
8258
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008259 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8260 {
8261 dump_bssid(pRoamInfo->bssid);
8262 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008263 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008264 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008265#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308266 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008267}
8268#endif //FEATURE_WLAN_LFR
8269
Yue Maef608272013-04-08 23:09:17 -07008270#ifdef FEATURE_WLAN_LFR_METRICS
8271/*
8272 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8273 * 802.11r/LFR metrics reporting function to report preauth initiation
8274 *
8275 */
8276#define MAX_LFR_METRICS_EVENT_LENGTH 100
8277VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8278 tCsrRoamInfo *pRoamInfo)
8279{
8280 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8281 union iwreq_data wrqu;
8282
8283 ENTER();
8284
8285 if (NULL == pAdapter)
8286 {
8287 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8288 return VOS_STATUS_E_FAILURE;
8289 }
8290
8291 /* create the event */
8292 memset(&wrqu, 0, sizeof(wrqu));
8293 memset(metrics_notification, 0, sizeof(metrics_notification));
8294
8295 wrqu.data.pointer = metrics_notification;
8296 wrqu.data.length = scnprintf(metrics_notification,
8297 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8298 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8299
8300 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8301
8302 EXIT();
8303
8304 return VOS_STATUS_SUCCESS;
8305}
8306
8307/*
8308 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8309 * 802.11r/LFR metrics reporting function to report preauth completion
8310 * or failure
8311 */
8312VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8313 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8314{
8315 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8316 union iwreq_data wrqu;
8317
8318 ENTER();
8319
8320 if (NULL == pAdapter)
8321 {
8322 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8323 return VOS_STATUS_E_FAILURE;
8324 }
8325
8326 /* create the event */
8327 memset(&wrqu, 0, sizeof(wrqu));
8328 memset(metrics_notification, 0, sizeof(metrics_notification));
8329
8330 scnprintf(metrics_notification, sizeof(metrics_notification),
8331 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8332 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8333
8334 if (1 == preauth_status)
8335 strncat(metrics_notification, " TRUE", 5);
8336 else
8337 strncat(metrics_notification, " FALSE", 6);
8338
8339 wrqu.data.pointer = metrics_notification;
8340 wrqu.data.length = strlen(metrics_notification);
8341
8342 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8343
8344 EXIT();
8345
8346 return VOS_STATUS_SUCCESS;
8347}
8348
8349/*
8350 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8351 * 802.11r/LFR metrics reporting function to report handover initiation
8352 *
8353 */
8354VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8355 tCsrRoamInfo *pRoamInfo)
8356{
8357 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8358 union iwreq_data wrqu;
8359
8360 ENTER();
8361
8362 if (NULL == pAdapter)
8363 {
8364 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8365 return VOS_STATUS_E_FAILURE;
8366 }
8367
8368 /* create the event */
8369 memset(&wrqu, 0, sizeof(wrqu));
8370 memset(metrics_notification, 0, sizeof(metrics_notification));
8371
8372 wrqu.data.pointer = metrics_notification;
8373 wrqu.data.length = scnprintf(metrics_notification,
8374 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8375 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8376
8377 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8378
8379 EXIT();
8380
8381 return VOS_STATUS_SUCCESS;
8382}
8383#endif
8384
Jeff Johnson295189b2012-06-20 16:38:30 -07008385/*
8386 * FUNCTION: hdd_cfg80211_scan_done_callback
8387 * scanning callback function, called after finishing scan
8388 *
8389 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308390static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8392{
8393 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308394 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008396 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8397 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 struct cfg80211_scan_request *req = NULL;
8399 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308400 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308401 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008402
8403 ENTER();
8404
8405 hddLog(VOS_TRACE_LEVEL_INFO,
8406 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008407 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 __func__, halHandle, pContext, (int) scanId, (int) status);
8409
Kiet Lamac06e2c2013-10-23 16:25:07 +05308410 pScanInfo->mScanPendingCounter = 0;
8411
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308413 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 &pScanInfo->scan_req_completion_event,
8415 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308416 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308418 hddLog(VOS_TRACE_LEVEL_ERROR,
8419 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008421 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 }
8423
Yue Maef608272013-04-08 23:09:17 -07008424 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 {
8426 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008427 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 }
8429
8430 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308431 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 {
8433 hddLog(VOS_TRACE_LEVEL_INFO,
8434 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008435 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008436 (int) scanId);
8437 }
8438
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308439 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 pAdapter);
8441
8442 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008444
8445
8446 /* If any client wait scan result through WEXT
8447 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008448 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 {
8450 /* The other scan request waiting for current scan finish
8451 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008452 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008454 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 }
8456 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008457 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 {
8459 struct net_device *dev = pAdapter->dev;
8460 union iwreq_data wrqu;
8461 int we_event;
8462 char *msg;
8463
8464 memset(&wrqu, '\0', sizeof(wrqu));
8465 we_event = SIOCGIWSCAN;
8466 msg = NULL;
8467 wireless_send_event(dev, we_event, &wrqu, msg);
8468 }
8469 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008470 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471
8472 /* Get the Scan Req */
8473 req = pAdapter->request;
8474
8475 if (!req)
8476 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008477 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008478 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008479 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 }
8481
8482 /*
8483 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308484 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 req->n_ssids = 0;
8486 req->n_channels = 0;
8487 req->ie = 0;
8488
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008490 /* Scan is no longer pending */
8491 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008492
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008493 /*
8494 * cfg80211_scan_done informing NL80211 about completion
8495 * of scanning
8496 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308497 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8498 {
8499 aborted = true;
8500 }
8501 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008502 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008503
Jeff Johnsone7245742012-09-05 17:12:55 -07008504allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008505 /* release the wake lock at the end of the scan*/
8506 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008507
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008508 /* Acquire wakelock to handle the case where APP's tries to suspend
8509 * immediatly after the driver gets connect request(i.e after scan)
8510 * from supplicant, this result in app's is suspending and not able
8511 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308512 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008513
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008514#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308515 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8516 {
8517 wlan_hdd_tdls_scan_done_callback(pAdapter);
8518 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008519#endif
8520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 EXIT();
8522 return 0;
8523}
8524
8525/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308526 * FUNCTION: hdd_isConnectionInProgress
8527 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008528 *
8529 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308530v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008531{
8532 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8533 hdd_station_ctx_t *pHddStaCtx = NULL;
8534 hdd_adapter_t *pAdapter = NULL;
8535 VOS_STATUS status = 0;
8536 v_U8_t staId = 0;
8537 v_U8_t *staMac = NULL;
8538
c_hpothu9b781ba2013-12-30 20:57:45 +05308539 if (TRUE == pHddCtx->btCoexModeSet)
8540 {
8541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308542 FL("BTCoex Mode operation in progress"));
8543 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308544 }
8545
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008546 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8547
8548 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8549 {
8550 pAdapter = pAdapterNode->pAdapter;
8551
8552 if( pAdapter )
8553 {
8554 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308555 "%s: Adapter with device mode %s (%d) exists",
8556 __func__, hdd_device_modetoString(pAdapter->device_mode),
8557 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308558 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8559 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8560 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8561 (eConnectionState_Connecting ==
8562 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8563 {
8564 hddLog(VOS_TRACE_LEVEL_ERROR,
8565 "%s: %p(%d) Connection is in progress", __func__,
8566 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8567 return VOS_TRUE;
8568 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008569 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308570 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8571 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008572 {
8573 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8574 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308575 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008576 {
8577 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8578 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008579 "%s: client " MAC_ADDRESS_STR
8580 " is in the middle of WPS/EAPOL exchange.", __func__,
8581 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308582 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008583 }
8584 }
8585 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8586 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8587 {
8588 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308590 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008591 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8592 {
8593 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8594
8595 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008596 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8597 "middle of WPS/EAPOL exchange.", __func__,
8598 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308599 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008600 }
8601 }
8602 }
8603 }
8604 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8605 pAdapterNode = pNext;
8606 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308607 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308608}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008609
8610/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308611 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 * this scan respond to scan trigger and update cfg80211 scan database
8613 * later, scan dump command can be used to recieve scan results
8614 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308615int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008616#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8617 struct net_device *dev,
8618#endif
8619 struct cfg80211_scan_request *request)
8620{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308621 hdd_adapter_t *pAdapter = NULL;
8622 hdd_context_t *pHddCtx = NULL;
8623 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308624 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 tCsrScanRequest scanRequest;
8626 tANI_U8 *channelList = NULL, i;
8627 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308628 int status;
8629 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008631
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308632#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8633 struct net_device *dev = NULL;
8634 if (NULL == request)
8635 {
8636 hddLog(VOS_TRACE_LEVEL_ERROR,
8637 "%s: scan req param null", __func__);
8638 return -EINVAL;
8639 }
8640 dev = request->wdev->netdev;
8641#endif
8642
8643 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8644 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8645 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8646
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 ENTER();
8648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308649
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8651 __func__, hdd_device_modetoString(pAdapter->device_mode),
8652 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008653
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308654 status = wlan_hdd_validate_context(pHddCtx);
8655
8656 if (0 != status)
8657 {
8658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8659 "%s: HDD context is not valid", __func__);
8660 return status;
8661 }
8662
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308663 if (NULL == pwextBuf)
8664 {
8665 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8666 __func__);
8667 return -EIO;
8668 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308669 cfg_param = pHddCtx->cfg_ini;
8670 pScanInfo = &pHddCtx->scan_info;
8671
Jeff Johnson295189b2012-06-20 16:38:30 -07008672#ifdef WLAN_BTAMP_FEATURE
8673 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008674 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008676 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 "%s: No scanning when AMP is on", __func__);
8678 return -EOPNOTSUPP;
8679 }
8680#endif
8681 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008682 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008684 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308685 "%s: Not scanning on device_mode = %s (%d)",
8686 __func__, hdd_device_modetoString(pAdapter->device_mode),
8687 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 return -EOPNOTSUPP;
8689 }
8690
8691 if (TRUE == pScanInfo->mScanPending)
8692 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308693 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8694 {
8695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8696 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008697 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008698 }
8699
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308700 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008701 //Channel and action frame is pending
8702 //Otherwise Cancel Remain On Channel and allow Scan
8703 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008704 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008705 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008707 return -EBUSY;
8708 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008709#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008710 /* if tdls disagree scan right now, return immediately.
8711 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8712 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8713 */
8714 status = wlan_hdd_tdls_scan_callback (pAdapter,
8715 wiphy,
8716#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8717 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008718#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008719 request);
8720 if(status <= 0)
8721 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308722 if(!status)
8723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8724 "scan rejected %d", __func__, status);
8725 else
8726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8727 __func__, status);
8728
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008729 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008730 }
8731#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008732
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8734 {
8735 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008736 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008739 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8740 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308741 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 "%s: MAX TM Level Scan not allowed", __func__);
8743 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308744 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8747
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008748 /* Check if scan is allowed at this point of time.
8749 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308750 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008751 {
8752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8753 return -EBUSY;
8754 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308755
Jeff Johnson295189b2012-06-20 16:38:30 -07008756 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8757
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308758 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8759 (int)request->n_ssids);
8760
8761 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8762 * Becasue of this, driver is assuming that this is not wildcard scan and so
8763 * is not aging out the scan results.
8764 */
8765 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308767 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308769
8770 if ((request->ssids) && (0 < request->n_ssids))
8771 {
8772 tCsrSSIDInfo *SsidInfo;
8773 int j;
8774 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8775 /* Allocate num_ssid tCsrSSIDInfo structure */
8776 SsidInfo = scanRequest.SSIDs.SSIDList =
8777 ( tCsrSSIDInfo *)vos_mem_malloc(
8778 request->n_ssids*sizeof(tCsrSSIDInfo));
8779
8780 if(NULL == scanRequest.SSIDs.SSIDList)
8781 {
8782 hddLog(VOS_TRACE_LEVEL_ERROR,
8783 "%s: memory alloc failed SSIDInfo buffer", __func__);
8784 return -ENOMEM;
8785 }
8786
8787 /* copy all the ssid's and their length */
8788 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8789 {
8790 /* get the ssid length */
8791 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8792 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8793 SsidInfo->SSID.length);
8794 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8795 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8796 j, SsidInfo->SSID.ssId);
8797 }
8798 /* set the scan type to active */
8799 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8800 }
8801 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308803 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8804 TRACE_CODE_HDD_CFG80211_SCAN,
8805 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 /* set the scan type to active */
8807 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308809 else
8810 {
8811 /*Set the scan type to default type, in this case it is ACTIVE*/
8812 scanRequest.scanType = pScanInfo->scan_mode;
8813 }
8814 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8815 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008816
8817 /* set BSSType to default type */
8818 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8819
8820 /*TODO: scan the requested channels only*/
8821
8822 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308823 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008824 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308825 hddLog(VOS_TRACE_LEVEL_WARN,
8826 "No of Scan Channels exceeded limit: %d", request->n_channels);
8827 request->n_channels = MAX_CHANNEL;
8828 }
8829
8830 hddLog(VOS_TRACE_LEVEL_INFO,
8831 "No of Scan Channels: %d", request->n_channels);
8832
8833
8834 if( request->n_channels )
8835 {
8836 char chList [(request->n_channels*5)+1];
8837 int len;
8838 channelList = vos_mem_malloc( request->n_channels );
8839 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308840 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308841 hddLog(VOS_TRACE_LEVEL_ERROR,
8842 "%s: memory alloc failed channelList", __func__);
8843 status = -ENOMEM;
8844 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308845 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308846
8847 for( i = 0, len = 0; i < request->n_channels ; i++ )
8848 {
8849 channelList[i] = request->channels[i]->hw_value;
8850 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8851 }
8852
Nirav Shah20ac06f2013-12-12 18:14:06 +05308853 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308854 "Channel-List: %s ", chList);
8855 }
c_hpothu53512302014-04-15 18:49:53 +05308856
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308857 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8858 scanRequest.ChannelInfo.ChannelList = channelList;
8859
8860 /* set requestType to full scan */
8861 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8862
8863 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8864 * search (Flush on both full scan and social scan but not on single
8865 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8866 */
8867
8868 /* Supplicant does single channel scan after 8-way handshake
8869 * and in that case driver shoudnt flush scan results. If
8870 * driver flushes the scan results here and unfortunately if
8871 * the AP doesnt respond to our probe req then association
8872 * fails which is not desired
8873 */
8874
8875 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8876 {
8877 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8878 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8879 pAdapter->sessionId );
8880 }
8881
8882 if( request->ie_len )
8883 {
8884 /* save this for future association (join requires this) */
8885 /*TODO: Array needs to be converted to dynamic allocation,
8886 * as multiple ie.s can be sent in cfg80211_scan_request structure
8887 * CR 597966
8888 */
8889 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8890 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8891 pScanInfo->scanAddIE.length = request->ie_len;
8892
8893 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8894 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8895 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308897 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308899 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8900 memcpy( pwextBuf->roamProfile.addIEScan,
8901 request->ie, request->ie_len);
8902 }
8903 else
8904 {
8905 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8906 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 }
8908
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308909 }
8910 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8911 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8912
8913 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8914 request->ie_len);
8915 if (pP2pIe != NULL)
8916 {
8917#ifdef WLAN_FEATURE_P2P_DEBUG
8918 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8919 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8920 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308921 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308922 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8923 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8924 "Go nego completed to Connection is started");
8925 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8926 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308927 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308928 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8929 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308931 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8932 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8933 "Disconnected state to Connection is started");
8934 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8935 "for 4way Handshake");
8936 }
8937#endif
8938
8939 /* no_cck will be set during p2p find to disable 11b rates */
8940 if(TRUE == request->no_cck)
8941 {
8942 hddLog(VOS_TRACE_LEVEL_INFO,
8943 "%s: This is a P2P Search", __func__);
8944 scanRequest.p2pSearch = 1;
8945
8946 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308947 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308948 /* set requestType to P2P Discovery */
8949 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8950 }
8951
8952 /*
8953 Skip Dfs Channel in case of P2P Search
8954 if it is set in ini file
8955 */
8956 if(cfg_param->skipDfsChnlInP2pSearch)
8957 {
8958 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308959 }
8960 else
8961 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308962 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05308963 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008964
Agarwal Ashish4f616132013-12-30 23:32:50 +05308965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 }
8967 }
8968
8969 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
8970
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008971 /* acquire the wakelock to avoid the apps suspend during the scan. To
8972 * address the following issues.
8973 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
8974 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
8975 * for long time, this result in apps running at full power for long time.
8976 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
8977 * be stuck in full power because of resume BMPS
8978 */
8979 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008980
Nirav Shah20ac06f2013-12-12 18:14:06 +05308981 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8982 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308983 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
8984 scanRequest.requestType, scanRequest.scanType,
8985 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05308986 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
8987
Jeff Johnsone7245742012-09-05 17:12:55 -07008988 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 pAdapter->sessionId, &scanRequest, &scanId,
8990 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07008991
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 if (eHAL_STATUS_SUCCESS != status)
8993 {
8994 hddLog(VOS_TRACE_LEVEL_ERROR,
8995 "%s: sme_ScanRequest returned error %d", __func__, status);
8996 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07008997 if(eHAL_STATUS_RESOURCES == status)
8998 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9000 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009001 status = -EBUSY;
9002 } else {
9003 status = -EIO;
9004 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009005 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 goto free_mem;
9007 }
9008
9009 pScanInfo->mScanPending = TRUE;
9010 pAdapter->request = request;
9011 pScanInfo->scanId = scanId;
9012
9013 complete(&pScanInfo->scan_req_completion_event);
9014
9015free_mem:
9016 if( scanRequest.SSIDs.SSIDList )
9017 {
9018 vos_mem_free(scanRequest.SSIDs.SSIDList);
9019 }
9020
9021 if( channelList )
9022 vos_mem_free( channelList );
9023
9024 EXIT();
9025
9026 return status;
9027}
9028
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309029int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9030#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9031 struct net_device *dev,
9032#endif
9033 struct cfg80211_scan_request *request)
9034{
9035 int ret;
9036
9037 vos_ssr_protect(__func__);
9038 ret = __wlan_hdd_cfg80211_scan(wiphy,
9039#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9040 dev,
9041#endif
9042 request);
9043 vos_ssr_unprotect(__func__);
9044
9045 return ret;
9046}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009047
9048void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9049{
9050 v_U8_t iniDot11Mode =
9051 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9052 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9053
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309054 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9055 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009056 switch ( iniDot11Mode )
9057 {
9058 case eHDD_DOT11_MODE_AUTO:
9059 case eHDD_DOT11_MODE_11ac:
9060 case eHDD_DOT11_MODE_11ac_ONLY:
9061#ifdef WLAN_FEATURE_11AC
9062 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9063#else
9064 hddDot11Mode = eHDD_DOT11_MODE_11n;
9065#endif
9066 break;
9067 case eHDD_DOT11_MODE_11n:
9068 case eHDD_DOT11_MODE_11n_ONLY:
9069 hddDot11Mode = eHDD_DOT11_MODE_11n;
9070 break;
9071 default:
9072 hddDot11Mode = iniDot11Mode;
9073 break;
9074 }
9075 /* This call decides required channel bonding mode */
9076 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9077 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9078 operationChannel);
9079}
9080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081/*
9082 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309083 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309085int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009086 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009087{
9088 int status = 0;
9089 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009090 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 v_U32_t roamId;
9092 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 eCsrAuthType RSNAuthType;
9094
9095 ENTER();
9096
9097 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009098 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9099
9100 status = wlan_hdd_validate_context(pHddCtx);
9101 if (status)
9102 {
9103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9104 "%s: HDD context is not valid!", __func__);
9105 return status;
9106 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309107
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9109 {
9110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9111 return -EINVAL;
9112 }
9113
9114 pRoamProfile = &pWextState->roamProfile;
9115
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309116 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009118 hdd_station_ctx_t *pHddStaCtx;
9119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009120
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309121 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009122 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9123 {
9124 /*QoS not enabled in cfg file*/
9125 pRoamProfile->uapsd_mask = 0;
9126 }
9127 else
9128 {
9129 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309130 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9132 }
9133
9134 pRoamProfile->SSIDs.numOfSSIDs = 1;
9135 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9136 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309137 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9139 ssid, ssid_len);
9140
9141 if (bssid)
9142 {
9143 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9144 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9145 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309146 /* Save BSSID in seperate variable as well, as RoamProfile
9147 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 case of join failure we should send valid BSSID to supplicant
9149 */
9150 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9151 WNI_CFG_BSSID_LEN);
9152 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009153 else
9154 {
9155 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009157
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309158 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9159 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9161 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309162 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 /*set gen ie*/
9164 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9165 /*set auth*/
9166 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9167 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009168#ifdef FEATURE_WLAN_WAPI
9169 if (pAdapter->wapi_info.nWapiMode)
9170 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009171 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 switch (pAdapter->wapi_info.wapiAuthMode)
9173 {
9174 case WAPI_AUTH_MODE_PSK:
9175 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009176 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 pAdapter->wapi_info.wapiAuthMode);
9178 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9179 break;
9180 }
9181 case WAPI_AUTH_MODE_CERT:
9182 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009183 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 pAdapter->wapi_info.wapiAuthMode);
9185 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9186 break;
9187 }
9188 } // End of switch
9189 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9190 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9191 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009192 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 pRoamProfile->AuthType.numEntries = 1;
9194 pRoamProfile->EncryptionType.numEntries = 1;
9195 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9196 pRoamProfile->mcEncryptionType.numEntries = 1;
9197 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9198 }
9199 }
9200#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309201#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309202 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309203 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9204 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9205 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309206 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9207 sizeof (tSirGtkOffloadParams));
9208 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309209 }
9210#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 pRoamProfile->csrPersona = pAdapter->device_mode;
9212
Jeff Johnson32d95a32012-09-10 13:15:23 -07009213 if( operatingChannel )
9214 {
9215 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9216 pRoamProfile->ChannelInfo.numOfChannels = 1;
9217 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009218 else
9219 {
9220 pRoamProfile->ChannelInfo.ChannelList = NULL;
9221 pRoamProfile->ChannelInfo.numOfChannels = 0;
9222 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009223 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9224 {
9225 hdd_select_cbmode(pAdapter,operatingChannel);
9226 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309227
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009228 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9229 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309230 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009231 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009232 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9233 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309234 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9235 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309236 {
9237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9238 "%s: Set HDD connState to eConnectionState_Connecting",
9239 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009240 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9241 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309242 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309243 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 pAdapter->sessionId, pRoamProfile, &roamId);
9245
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309246 if ((eHAL_STATUS_SUCCESS != status) &&
9247 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9248 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309249
9250 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9252 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9253 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309254 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009255 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309256 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009257
9258 pRoamProfile->ChannelInfo.ChannelList = NULL;
9259 pRoamProfile->ChannelInfo.numOfChannels = 0;
9260
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 }
9262 else
9263 {
9264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9265 return -EINVAL;
9266 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009267 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 return status;
9269}
9270
9271/*
9272 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9273 * This function is used to set the authentication type (OPEN/SHARED).
9274 *
9275 */
9276static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9277 enum nl80211_auth_type auth_type)
9278{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309279 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9281
9282 ENTER();
9283
9284 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309285 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309288 hddLog(VOS_TRACE_LEVEL_INFO,
9289 "%s: set authentication type to AUTOSWITCH", __func__);
9290 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9291 break;
9292
9293 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009294#ifdef WLAN_FEATURE_VOWIFI_11R
9295 case NL80211_AUTHTYPE_FT:
9296#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309297 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 "%s: set authentication type to OPEN", __func__);
9299 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9300 break;
9301
9302 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 "%s: set authentication type to SHARED", __func__);
9305 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9306 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009307#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 "%s: set authentication type to CCKM WPA", __func__);
9311 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9312 break;
9313#endif
9314
9315
9316 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309317 hddLog(VOS_TRACE_LEVEL_ERROR,
9318 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 auth_type);
9320 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9321 return -EINVAL;
9322 }
9323
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309324 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 pHddStaCtx->conn_info.authType;
9326 return 0;
9327}
9328
9329/*
9330 * FUNCTION: wlan_hdd_set_akm_suite
9331 * This function is used to set the key mgmt type(PSK/8021x).
9332 *
9333 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 u32 key_mgmt
9336 )
9337{
9338 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9339 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 /*set key mgmt type*/
9342 switch(key_mgmt)
9343 {
9344 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309345#ifdef WLAN_FEATURE_VOWIFI_11R
9346 case WLAN_AKM_SUITE_FT_PSK:
9347#endif
9348 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 __func__);
9350 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9351 break;
9352
9353 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309354#ifdef WLAN_FEATURE_VOWIFI_11R
9355 case WLAN_AKM_SUITE_FT_8021X:
9356#endif
9357 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 __func__);
9359 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9360 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009361#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009362#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9363#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9364 case WLAN_AKM_SUITE_CCKM:
9365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9366 __func__);
9367 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9368 break;
9369#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009370#ifndef WLAN_AKM_SUITE_OSEN
9371#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9372 case WLAN_AKM_SUITE_OSEN:
9373 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9374 __func__);
9375 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9376 break;
9377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009378
9379 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 __func__, key_mgmt);
9382 return -EINVAL;
9383
9384 }
9385 return 0;
9386}
9387
9388/*
9389 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309390 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 * (NONE/WEP40/WEP104/TKIP/CCMP).
9392 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9394 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 bool ucast
9396 )
9397{
9398 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309399 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9401
9402 ENTER();
9403
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309404 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 __func__, cipher);
9408 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9409 }
9410 else
9411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 {
9416 case IW_AUTH_CIPHER_NONE:
9417 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9418 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309421 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009422 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309425 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 case WLAN_CIPHER_SUITE_TKIP:
9429 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9430 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 case WLAN_CIPHER_SUITE_CCMP:
9433 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9434 break;
9435#ifdef FEATURE_WLAN_WAPI
9436 case WLAN_CIPHER_SUITE_SMS4:
9437 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9438 break;
9439#endif
9440
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009441#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 case WLAN_CIPHER_SUITE_KRK:
9443 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9444 break;
9445#endif
9446 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 __func__, cipher);
9449 return -EOPNOTSUPP;
9450 }
9451 }
9452
9453 if (ucast)
9454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 __func__, encryptionType);
9457 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9458 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309459 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 encryptionType;
9461 }
9462 else
9463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 __func__, encryptionType);
9466 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9467 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9468 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9469 }
9470
9471 return 0;
9472}
9473
9474
9475/*
9476 * FUNCTION: wlan_hdd_cfg80211_set_ie
9477 * This function is used to parse WPA/RSN IE's.
9478 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9480 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 size_t ie_len
9482 )
9483{
9484 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9485 u8 *genie = ie;
9486 v_U16_t remLen = ie_len;
9487#ifdef FEATURE_WLAN_WAPI
9488 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9489 u16 *tmp;
9490 v_U16_t akmsuiteCount;
9491 int *akmlist;
9492#endif
9493 ENTER();
9494
9495 /* clear previous assocAddIE */
9496 pWextState->assocAddIE.length = 0;
9497 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009498 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009499
9500 while (remLen >= 2)
9501 {
9502 v_U16_t eLen = 0;
9503 v_U8_t elementId;
9504 elementId = *genie++;
9505 eLen = *genie++;
9506 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507
Arif Hussain6d2a3322013-11-17 19:50:10 -08009508 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309510
9511 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309513 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009514 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 -07009515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309516 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 "%s: Invalid WPA IE", __func__);
9518 return -EINVAL;
9519 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309520 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 {
9522 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309523 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309525
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9527 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009528 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9529 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 VOS_ASSERT(0);
9531 return -ENOMEM;
9532 }
9533 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9534 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9535 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9538 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9539 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9540 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309541 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9542 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9544 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9545 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9546 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9547 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309549 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309550 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 {
9552 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9557 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009558 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9559 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 VOS_ASSERT(0);
9561 return -ENOMEM;
9562 }
9563 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9564 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9565 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9568 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9569 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009570#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9572 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 /*Consider WFD IE, only for P2P Client */
9574 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9575 {
9576 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309577 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309579
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9581 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009582 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9583 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 VOS_ASSERT(0);
9585 return -ENOMEM;
9586 }
9587 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9588 // WPS IE + P2P IE + WFD IE
9589 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9590 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9593 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9594 }
9595#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009596 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009598 HS20_OUI_TYPE_SIZE)) )
9599 {
9600 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009602 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009603
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009604 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9605 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009606 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9607 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009608 VOS_ASSERT(0);
9609 return -ENOMEM;
9610 }
9611 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9612 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009613
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009614 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9615 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9616 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009617 /* Appending OSEN Information Element in Assiciation Request */
9618 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9619 OSEN_OUI_TYPE_SIZE)) )
9620 {
9621 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9622 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9623 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009624
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009625 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9626 {
9627 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9628 "Need bigger buffer space");
9629 VOS_ASSERT(0);
9630 return -ENOMEM;
9631 }
9632 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9633 pWextState->assocAddIE.length += eLen + 2;
9634
9635 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9636 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9637 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9638 }
9639
9640 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009641 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9642
9643 /* populating as ADDIE in beacon frames */
9644 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9645 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9646 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9647 {
9648 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9649 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9650 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9651 {
9652 hddLog(LOGE,
9653 "Coldn't pass "
9654 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9655 }
9656 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9657 else
9658 hddLog(LOGE,
9659 "Could not pass on "
9660 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9661
9662 /* IBSS mode doesn't contain params->proberesp_ies still
9663 beaconIE's need to be populated in probe response frames */
9664 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9665 {
9666 u16 rem_probe_resp_ie_len = eLen + 2;
9667 u8 probe_rsp_ie_len[3] = {0};
9668 u8 counter = 0;
9669
9670 /* Check Probe Resp Length if it is greater then 255 then
9671 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9672 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9673 not able Store More then 255 bytes into One Variable */
9674
9675 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9676 {
9677 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9678 {
9679 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9680 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9681 }
9682 else
9683 {
9684 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9685 rem_probe_resp_ie_len = 0;
9686 }
9687 }
9688
9689 rem_probe_resp_ie_len = 0;
9690
9691 if (probe_rsp_ie_len[0] > 0)
9692 {
9693 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9694 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9695 (tANI_U8*)(genie - 2),
9696 probe_rsp_ie_len[0], NULL,
9697 eANI_BOOLEAN_FALSE)
9698 == eHAL_STATUS_FAILURE)
9699 {
9700 hddLog(LOGE,
9701 "Could not pass"
9702 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9703 }
9704 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9705 }
9706
9707 if (probe_rsp_ie_len[1] > 0)
9708 {
9709 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9710 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9711 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9712 probe_rsp_ie_len[1], NULL,
9713 eANI_BOOLEAN_FALSE)
9714 == eHAL_STATUS_FAILURE)
9715 {
9716 hddLog(LOGE,
9717 "Could not pass"
9718 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9719 }
9720 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9721 }
9722
9723 if (probe_rsp_ie_len[2] > 0)
9724 {
9725 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9726 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9727 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9728 probe_rsp_ie_len[2], NULL,
9729 eANI_BOOLEAN_FALSE)
9730 == eHAL_STATUS_FAILURE)
9731 {
9732 hddLog(LOGE,
9733 "Could not pass"
9734 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9735 }
9736 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9737 }
9738
9739 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9740 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9741 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9742 {
9743 hddLog(LOGE,
9744 "Could not pass"
9745 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9746 }
9747 }
9748 else
9749 {
9750 // Reset WNI_CFG_PROBE_RSP Flags
9751 wlan_hdd_reset_prob_rspies(pAdapter);
9752
9753 hddLog(VOS_TRACE_LEVEL_INFO,
9754 "%s: No Probe Response IE received in set beacon",
9755 __func__);
9756 }
9757 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 break;
9759 case DOT11F_EID_RSN:
9760 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9761 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9762 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9763 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9764 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9765 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009766 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9767 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009769 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009771 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309772
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009773 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9774 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009775 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9776 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009777 VOS_ASSERT(0);
9778 return -ENOMEM;
9779 }
9780 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9781 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309782
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009783 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9784 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9785 break;
9786 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009787#ifdef FEATURE_WLAN_WAPI
9788 case WLAN_EID_WAPI:
9789 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009790 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 pAdapter->wapi_info.nWapiMode);
9792 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309793 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 akmsuiteCount = WPA_GET_LE16(tmp);
9795 tmp = tmp + 1;
9796 akmlist = (int *)(tmp);
9797 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9798 {
9799 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9800 }
9801 else
9802 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009803 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 VOS_ASSERT(0);
9805 return -EINVAL;
9806 }
9807
9808 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9809 {
9810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009811 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309815 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009817 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9819 }
9820 break;
9821#endif
9822 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309823 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009825 /* when Unknown IE is received we should break and continue
9826 * to the next IE in the buffer instead we were returning
9827 * so changing this to break */
9828 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830 genie += eLen;
9831 remLen -= eLen;
9832 }
9833 EXIT();
9834 return 0;
9835}
9836
9837/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309838 * FUNCTION: hdd_isWPAIEPresent
9839 * Parse the received IE to find the WPA IE
9840 *
9841 */
9842static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9843{
9844 v_U8_t eLen = 0;
9845 v_U16_t remLen = ie_len;
9846 v_U8_t elementId = 0;
9847
9848 while (remLen >= 2)
9849 {
9850 elementId = *ie++;
9851 eLen = *ie++;
9852 remLen -= 2;
9853 if (eLen > remLen)
9854 {
9855 hddLog(VOS_TRACE_LEVEL_ERROR,
9856 "%s: IE length is wrong %d", __func__, eLen);
9857 return FALSE;
9858 }
9859 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9860 {
9861 /* OUI - 0x00 0X50 0XF2
9862 WPA Information Element - 0x01
9863 WPA version - 0x01*/
9864 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9865 return TRUE;
9866 }
9867 ie += eLen;
9868 remLen -= eLen;
9869 }
9870 return FALSE;
9871}
9872
9873/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309875 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 * parameters during connect operation.
9877 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309878int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 struct cfg80211_connect_params *req
9880 )
9881{
9882 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 ENTER();
9885
9886 /*set wpa version*/
9887 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9888
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309889 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309891 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009892 {
9893 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9894 }
9895 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9896 {
9897 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9898 }
9899 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309900
9901 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 pWextState->wpaVersion);
9903
9904 /*set authentication type*/
9905 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9906
9907 if (0 > status)
9908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 "%s: failed to set authentication type ", __func__);
9911 return status;
9912 }
9913
9914 /*set key mgmt type*/
9915 if (req->crypto.n_akm_suites)
9916 {
9917 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9918 if (0 > status)
9919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 __func__);
9922 return status;
9923 }
9924 }
9925
9926 /*set pairwise cipher type*/
9927 if (req->crypto.n_ciphers_pairwise)
9928 {
9929 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9930 req->crypto.ciphers_pairwise[0], true);
9931 if (0 > status)
9932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309933 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 "%s: failed to set unicast cipher type", __func__);
9935 return status;
9936 }
9937 }
9938 else
9939 {
9940 /*Reset previous cipher suite to none*/
9941 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9942 if (0 > status)
9943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309944 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 "%s: failed to set unicast cipher type", __func__);
9946 return status;
9947 }
9948 }
9949
9950 /*set group cipher type*/
9951 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9952 false);
9953
9954 if (0 > status)
9955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 __func__);
9958 return status;
9959 }
9960
Chet Lanctot186b5732013-03-18 10:26:30 -07009961#ifdef WLAN_FEATURE_11W
9962 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
9963#endif
9964
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
9966 if (req->ie_len)
9967 {
9968 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
9969 if ( 0 > status)
9970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 __func__);
9973 return status;
9974 }
9975 }
9976
9977 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309978 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 {
9980 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
9981 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
9982 )
9983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309984 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07009985 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
9986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 __func__);
9989 return -EOPNOTSUPP;
9990 }
9991 else
9992 {
9993 u8 key_len = req->key_len;
9994 u8 key_idx = req->key_idx;
9995
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309996 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 && (CSR_MAX_NUM_KEY > key_idx)
9998 )
9999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010000 hddLog(VOS_TRACE_LEVEL_INFO,
10001 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 __func__, key_idx, key_len);
10003 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010004 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010006 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 (u8)key_len;
10008 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10009 }
10010 }
10011 }
10012 }
10013
10014 return status;
10015}
10016
10017/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010018 * FUNCTION: wlan_hdd_try_disconnect
10019 * This function is used to disconnect from previous
10020 * connection
10021 */
10022static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10023{
10024 long ret = 0;
10025 hdd_station_ctx_t *pHddStaCtx;
10026 eMib_dot11DesiredBssType connectedBssType;
10027
10028 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10029
10030 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10031
10032 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10033 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10034 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10035 {
10036 /* Issue disconnect to CSR */
10037 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10038 if( eHAL_STATUS_SUCCESS ==
10039 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10040 pAdapter->sessionId,
10041 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10042 {
10043 ret = wait_for_completion_interruptible_timeout(
10044 &pAdapter->disconnect_comp_var,
10045 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10046 if (0 >= ret)
10047 {
10048 hddLog(LOGE, FL("Failed to receive disconnect event"));
10049 return -EALREADY;
10050 }
10051 }
10052 }
10053 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10054 {
10055 ret = wait_for_completion_interruptible_timeout(
10056 &pAdapter->disconnect_comp_var,
10057 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10058 if (0 >= ret)
10059 {
10060 hddLog(LOGE, FL("Failed to receive disconnect event"));
10061 return -EALREADY;
10062 }
10063 }
10064
10065 return 0;
10066}
10067
10068/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010069 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010070 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 * parameters during connect operation.
10072 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010073static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 struct net_device *ndev,
10075 struct cfg80211_connect_params *req
10076 )
10077{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010078 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010081 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010082
10083 ENTER();
10084
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10086 TRACE_CODE_HDD_CFG80211_CONNECT,
10087 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010088 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010089 "%s: device_mode = %s (%d)", __func__,
10090 hdd_device_modetoString(pAdapter->device_mode),
10091 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010092
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010094 if (!pHddCtx)
10095 {
10096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10097 "%s: HDD context is null", __func__);
10098 return VOS_STATUS_E_FAILURE;
10099 }
10100
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010101 status = wlan_hdd_validate_context(pHddCtx);
10102
10103 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10106 "%s: HDD context is not valid", __func__);
10107 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 }
10109
10110#ifdef WLAN_BTAMP_FEATURE
10111 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010116 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 }
10118#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010119
10120 //If Device Mode is Station Concurrent Sessions Exit BMps
10121 //P2P Mode will be taken care in Open/close adapter
10122 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10123 (vos_concurrent_sessions_running()))
10124 {
10125 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10126 }
10127
10128 /*Try disconnecting if already in connected state*/
10129 status = wlan_hdd_try_disconnect(pAdapter);
10130 if ( 0 > status)
10131 {
10132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10133 " connection"));
10134 return -EALREADY;
10135 }
10136
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010138 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010139
10140 if ( 0 > status)
10141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 __func__);
10144 return status;
10145 }
10146
Mohit Khanna765234a2012-09-11 15:08:35 -070010147 if ( req->channel )
10148 {
10149 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10150 req->ssid_len, req->bssid,
10151 req->channel->hw_value);
10152 }
10153 else
10154 {
10155 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010156 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159 if (0 > status)
10160 {
10161 //ReEnable BMPS if disabled
10162 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10163 (NULL != pHddCtx))
10164 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010165 if (pHddCtx->hdd_wlan_suspended)
10166 {
10167 hdd_set_pwrparams(pHddCtx);
10168 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 //ReEnable Bmps and Imps back
10170 hdd_enable_bmps_imps(pHddCtx);
10171 }
10172
10173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10174 return status;
10175 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010176 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 EXIT();
10178 return status;
10179}
10180
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010181static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10182 struct net_device *ndev,
10183 struct cfg80211_connect_params *req)
10184{
10185 int ret;
10186 vos_ssr_protect(__func__);
10187 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10188 vos_ssr_unprotect(__func__);
10189
10190 return ret;
10191}
Jeff Johnson295189b2012-06-20 16:38:30 -070010192
10193/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010194 * FUNCTION: wlan_hdd_disconnect
10195 * This function is used to issue a disconnect request to SME
10196 */
10197int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10198{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010199 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010200 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010201 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10202
10203 status = wlan_hdd_validate_context(pHddCtx);
10204
10205 if (0 != status)
10206 {
10207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10208 "%s: HDD context is not valid", __func__);
10209 return status;
10210 }
10211
10212 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10214 "%s: Set HDD connState to eConnectionState_Disconnecting",
10215 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010216 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010217 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010218
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010219 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010220
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010221 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10222 pAdapter->sessionId, reason);
10223
10224 if ( 0 != status )
10225 {
10226 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010227 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010228 __func__, (int)status );
10229 return -EINVAL;
10230 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010231 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010232 &pAdapter->disconnect_comp_var,
10233 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010234 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010235 {
10236 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010237 "%s: Failed to disconnect, timed out", __func__);
10238 return -ETIMEDOUT;
10239 }
10240 else if (status == -ERESTARTSYS)
10241 {
10242 hddLog(VOS_TRACE_LEVEL_ERROR,
10243 "%s: Failed to disconnect, wait interrupted", __func__);
10244 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010245 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010246 /*stop tx queues*/
10247 netif_tx_disable(pAdapter->dev);
10248 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010249 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010250}
10251
10252
10253/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010254 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 * This function is used to issue a disconnect request to SME
10256 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010257static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 struct net_device *dev,
10259 u16 reason
10260 )
10261{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10263 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010267 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010268#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010269 tANI_U8 staIdx;
10270#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010273
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010274 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10275 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10276 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10278 __func__, hdd_device_modetoString(pAdapter->device_mode),
10279 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010280
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010281 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10282 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010283
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010284 status = wlan_hdd_validate_context(pHddCtx);
10285
10286 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10289 "%s: HDD context is not valid", __func__);
10290 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010292
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 if (NULL != pRoamProfile)
10294 {
10295 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010296 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10297 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010299 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010301 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 switch(reason)
10303 {
10304 case WLAN_REASON_MIC_FAILURE:
10305 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10306 break;
10307
10308 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10309 case WLAN_REASON_DISASSOC_AP_BUSY:
10310 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10311 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10312 break;
10313
10314 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10315 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010316 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10318 break;
10319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 default:
10321 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10322 break;
10323 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010324 pScanInfo = &pHddCtx->scan_info;
10325 if (pScanInfo->mScanPending)
10326 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010327 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010328 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010329 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10330 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010331 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010332
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010333#ifdef FEATURE_WLAN_TDLS
10334 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010335 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010336 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010337 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10338 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010339 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010340 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010341 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010342 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010343 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010344 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010345 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010346 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010347 pAdapter->sessionId,
10348 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010349 }
10350 }
10351#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010352 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010353 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10354 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 {
10356 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010357 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 __func__, (int)status );
10359 return -EINVAL;
10360 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010361 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010362 else
10363 {
10364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10365 "called while in %d state", __func__,
10366 pHddStaCtx->conn_info.connState);
10367 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 }
10369 else
10370 {
10371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10372 }
10373
10374 return status;
10375}
10376
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010377static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10378 struct net_device *dev,
10379 u16 reason
10380 )
10381{
10382 int ret;
10383 vos_ssr_protect(__func__);
10384 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10385 vos_ssr_unprotect(__func__);
10386
10387 return ret;
10388}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010389
Jeff Johnson295189b2012-06-20 16:38:30 -070010390/*
10391 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010392 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 * settings in IBSS mode.
10394 */
10395static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010396 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 struct cfg80211_ibss_params *params
10398 )
10399{
10400 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010401 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10403 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010404
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 ENTER();
10406
10407 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010408 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010409
10410 if (params->ie_len && ( NULL != params->ie) )
10411 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010412 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10413 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010414 {
10415 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10416 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10417 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010418 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010419 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010420 tDot11fIEWPA dot11WPAIE;
10421 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010422 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010423
Wilson Yang00256342013-10-10 23:13:38 -070010424 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010425 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10426 params->ie_len, DOT11F_EID_WPA);
10427 if ( NULL != ie )
10428 {
10429 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10430 // Unpack the WPA IE
10431 //Skip past the EID byte and length byte - and four byte WiFi OUI
10432 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10433 &ie[2+4],
10434 ie[1] - 4,
10435 &dot11WPAIE);
10436 /*Extract the multicast cipher, the encType for unicast
10437 cipher for wpa-none is none*/
10438 encryptionType =
10439 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10440 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010442
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10444
10445 if (0 > status)
10446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 __func__);
10449 return status;
10450 }
10451 }
10452
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010453 pWextState->roamProfile.AuthType.authType[0] =
10454 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10456
10457 if (params->privacy)
10458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010459 /* Security enabled IBSS, At this time there is no information available
10460 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010462 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010464 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 *enable privacy bit in beacons */
10466
10467 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10468 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010469 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10470 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10472 pWextState->roamProfile.EncryptionType.numEntries = 1;
10473 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 return status;
10475}
10476
10477/*
10478 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010479 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010481static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010482 struct net_device *dev,
10483 struct cfg80211_ibss_params *params
10484 )
10485{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010486 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10488 tCsrRoamProfile *pRoamProfile;
10489 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010490 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010492 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010493
10494 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010495
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010496 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10497 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10498 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010499 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010500 "%s: device_mode = %s (%d)", __func__,
10501 hdd_device_modetoString(pAdapter->device_mode),
10502 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010503
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010504 status = wlan_hdd_validate_context(pHddCtx);
10505
10506 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10509 "%s: HDD context is not valid", __func__);
10510 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 }
10512
10513 if (NULL == pWextState)
10514 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010515 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 __func__);
10517 return -EIO;
10518 }
10519
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010520 /*Try disconnecting if already in connected state*/
10521 status = wlan_hdd_try_disconnect(pAdapter);
10522 if ( 0 > status)
10523 {
10524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10525 " IBSS connection"));
10526 return -EALREADY;
10527 }
10528
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 pRoamProfile = &pWextState->roamProfile;
10530
10531 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010534 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 return -EINVAL;
10536 }
10537
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010538 /* BSSID is provided by upper layers hence no need to AUTO generate */
10539 if (NULL != params->bssid) {
10540 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10541 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10542 hddLog (VOS_TRACE_LEVEL_ERROR,
10543 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10544 return -EIO;
10545 }
10546 }
krunal sonie9002db2013-11-25 14:24:17 -080010547 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10548 {
10549 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10550 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10551 {
10552 hddLog (VOS_TRACE_LEVEL_ERROR,
10553 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10554 return -EIO;
10555 }
10556 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10557 if (!params->bssid)
10558 {
10559 hddLog (VOS_TRACE_LEVEL_ERROR,
10560 "%s:Failed memory allocation", __func__);
10561 return -EIO;
10562 }
10563 vos_mem_copy((v_U8_t *)params->bssid,
10564 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10565 VOS_MAC_ADDR_SIZE);
10566 alloc_bssid = VOS_TRUE;
10567 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010568
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010570 if (NULL !=
10571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10572 params->chandef.chan)
10573#else
10574 params->channel)
10575#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010576 {
10577 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010578 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10579 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10580 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10581 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010582
10583 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010585 ieee80211_frequency_to_channel(
10586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10587 params->chandef.chan->center_freq);
10588#else
10589 params->channel->center_freq);
10590#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010591
10592 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10593 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10596 __func__);
10597 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010599
10600 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010602 if (channelNum == validChan[indx])
10603 {
10604 break;
10605 }
10606 }
10607 if (indx >= numChans)
10608 {
10609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 __func__, channelNum);
10611 return -EINVAL;
10612 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010613 /* Set the Operational Channel */
10614 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10615 channelNum);
10616 pRoamProfile->ChannelInfo.numOfChannels = 1;
10617 pHddStaCtx->conn_info.operationChannel = channelNum;
10618 pRoamProfile->ChannelInfo.ChannelList =
10619 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 }
10621
10622 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010623 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 if (status < 0)
10625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 __func__);
10628 return status;
10629 }
10630
10631 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010633 params->ssid_len, params->bssid,
10634 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010635
10636 if (0 > status)
10637 {
10638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10639 return status;
10640 }
10641
krunal sonie9002db2013-11-25 14:24:17 -080010642 if (NULL != params->bssid &&
10643 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10644 alloc_bssid == VOS_TRUE)
10645 {
10646 vos_mem_free(params->bssid);
10647 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 return 0;
10649}
10650
10651/*
10652 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010653 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010655static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 struct net_device *dev
10657 )
10658{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10661 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010662 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10663 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010664
10665 ENTER();
10666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10668 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10669 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010670 status = wlan_hdd_validate_context(pHddCtx);
10671
10672 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010673 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10675 "%s: HDD context is not valid", __func__);
10676 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010677 }
10678
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010679 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10680 hdd_device_modetoString(pAdapter->device_mode),
10681 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 if (NULL == pWextState)
10683 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010684 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 __func__);
10686 return -EIO;
10687 }
10688
10689 pRoamProfile = &pWextState->roamProfile;
10690
10691 /* Issue disconnect only if interface type is set to IBSS */
10692 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10693 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010694 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 __func__);
10696 return -EINVAL;
10697 }
10698
10699 /* Issue Disconnect request */
10700 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10701 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10702 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10703
10704 return 0;
10705}
10706
10707/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010708 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 * This function is used to set the phy parameters
10710 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10711 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010712static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 u32 changed)
10714{
10715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10716 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010717 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010718
10719 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010720 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10721 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10722 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010723 status = wlan_hdd_validate_context(pHddCtx);
10724
10725 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010726 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10728 "%s: HDD context is not valid", __func__);
10729 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010730 }
10731
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10733 {
10734 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10735 WNI_CFG_RTS_THRESHOLD_STAMAX :
10736 wiphy->rts_threshold;
10737
10738 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010739 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010740 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 hddLog(VOS_TRACE_LEVEL_ERROR,
10742 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 __func__, rts_threshold);
10744 return -EINVAL;
10745 }
10746
10747 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10748 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 hddLog(VOS_TRACE_LEVEL_ERROR,
10752 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 __func__, rts_threshold);
10754 return -EIO;
10755 }
10756
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 rts_threshold);
10759 }
10760
10761 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10762 {
10763 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10764 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10765 wiphy->frag_threshold;
10766
10767 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010768 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010770 hddLog(VOS_TRACE_LEVEL_ERROR,
10771 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 frag_threshold);
10773 return -EINVAL;
10774 }
10775
10776 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10777 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010778 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010780 hddLog(VOS_TRACE_LEVEL_ERROR,
10781 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 __func__, frag_threshold);
10783 return -EIO;
10784 }
10785
10786 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10787 frag_threshold);
10788 }
10789
10790 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10791 || (changed & WIPHY_PARAM_RETRY_LONG))
10792 {
10793 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10794 wiphy->retry_short :
10795 wiphy->retry_long;
10796
10797 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10798 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 __func__, retry_value);
10802 return -EINVAL;
10803 }
10804
10805 if (changed & WIPHY_PARAM_RETRY_SHORT)
10806 {
10807 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10808 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010809 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010811 hddLog(VOS_TRACE_LEVEL_ERROR,
10812 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 __func__, retry_value);
10814 return -EIO;
10815 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010816 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 __func__, retry_value);
10818 }
10819 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10820 {
10821 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10822 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010823 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010825 hddLog(VOS_TRACE_LEVEL_ERROR,
10826 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 __func__, retry_value);
10828 return -EIO;
10829 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010830 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 __func__, retry_value);
10832 }
10833 }
10834
10835 return 0;
10836}
10837
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010838static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10839 u32 changed)
10840{
10841 int ret;
10842
10843 vos_ssr_protect(__func__);
10844 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10845 vos_ssr_unprotect(__func__);
10846
10847 return ret;
10848}
10849
Jeff Johnson295189b2012-06-20 16:38:30 -070010850/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010851 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 * This function is used to set the txpower
10853 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010854static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010855#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10856 struct wireless_dev *wdev,
10857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010858#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010859 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010860#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010861 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010862#endif
10863 int dbm)
10864{
10865 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010866 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10868 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010869 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010870
10871 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10873 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10874 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010875 status = wlan_hdd_validate_context(pHddCtx);
10876
10877 if (0 != status)
10878 {
10879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10880 "%s: HDD context is not valid", __func__);
10881 return status;
10882 }
10883
10884 hHal = pHddCtx->hHal;
10885
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10887 dbm, ccmCfgSetCallback,
10888 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010890 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10892 return -EIO;
10893 }
10894
10895 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10896 dbm);
10897
10898 switch(type)
10899 {
10900 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
10901 /* Fall through */
10902 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
10903 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
10904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
10906 __func__);
10907 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 }
10909 break;
10910 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 __func__);
10913 return -EOPNOTSUPP;
10914 break;
10915 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
10917 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 return -EIO;
10919 }
10920
10921 return 0;
10922}
10923
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010924static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
10925#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10926 struct wireless_dev *wdev,
10927#endif
10928#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10929 enum tx_power_setting type,
10930#else
10931 enum nl80211_tx_power_setting type,
10932#endif
10933 int dbm)
10934{
10935 int ret;
10936 vos_ssr_protect(__func__);
10937 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
10938#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10939 wdev,
10940#endif
10941#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
10942 type,
10943#else
10944 type,
10945#endif
10946 dbm);
10947 vos_ssr_unprotect(__func__);
10948
10949 return ret;
10950}
10951
Jeff Johnson295189b2012-06-20 16:38:30 -070010952/*
10953 * FUNCTION: wlan_hdd_cfg80211_get_txpower
10954 * This function is used to read the txpower
10955 */
Yue Maf49ba872013-08-19 12:04:25 -070010956static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
10957#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10958 struct wireless_dev *wdev,
10959#endif
10960 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070010961{
10962
10963 hdd_adapter_t *pAdapter;
10964 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010965 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010966
Jeff Johnsone7245742012-09-05 17:12:55 -070010967 ENTER();
10968
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010969 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010970
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010971 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010972 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10974 "%s: HDD context is not valid", __func__);
10975 *dbm = 0;
10976 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010977 }
10978
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
10980 if (NULL == pAdapter)
10981 {
10982 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
10983 return -ENOENT;
10984 }
10985
10986 wlan_hdd_get_classAstats(pAdapter);
10987 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
10988
Jeff Johnsone7245742012-09-05 17:12:55 -070010989 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 return 0;
10991}
10992
10993static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
10994 u8* mac, struct station_info *sinfo)
10995{
10996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10997 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10998 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053010999 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011000
11001 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11002 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011003
11004 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11005 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11006 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11007 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11008 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11009 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11010 tANI_U16 maxRate = 0;
11011 tANI_U16 myRate;
11012 tANI_U16 currentRate = 0;
11013 tANI_U8 maxSpeedMCS = 0;
11014 tANI_U8 maxMCSIdx = 0;
11015 tANI_U8 rateFlag = 1;
11016 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011017 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011018 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011019
Leo Chang6f8870f2013-03-26 18:11:36 -070011020#ifdef WLAN_FEATURE_11AC
11021 tANI_U32 vht_mcs_map;
11022 eDataRate11ACMaxMcs vhtMaxMcs;
11023#endif /* WLAN_FEATURE_11AC */
11024
Jeff Johnsone7245742012-09-05 17:12:55 -070011025 ENTER();
11026
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11028 (0 == ssidlen))
11029 {
11030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11031 " Invalid ssidlen, %d", __func__, ssidlen);
11032 /*To keep GUI happy*/
11033 return 0;
11034 }
11035
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011036 status = wlan_hdd_validate_context(pHddCtx);
11037
11038 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11041 "%s: HDD context is not valid", __func__);
11042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011043 }
11044
Jeff Johnson295189b2012-06-20 16:38:30 -070011045
Kiet Lam3b17fc82013-09-27 05:24:08 +053011046 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11047 sinfo->filled |= STATION_INFO_SIGNAL;
11048
c_hpothu09f19542014-05-30 21:53:31 +053011049 wlan_hdd_get_station_stats(pAdapter);
11050 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11051
11052 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011053 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11054 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11055 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11056 {
11057 rate_flags = pAdapter->maxRateFlags;
11058 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011059
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 //convert to the UI units of 100kbps
11061 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11062
11063#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011064 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 -070011065 sinfo->signal,
11066 pCfg->reportMaxLinkSpeed,
11067 myRate,
11068 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011069 (int) pCfg->linkSpeedRssiMid,
11070 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011071 (int) rate_flags,
11072 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011073#endif //LINKSPEED_DEBUG_ENABLED
11074
11075 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11076 {
11077 // we do not want to necessarily report the current speed
11078 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11079 {
11080 // report the max possible speed
11081 rssidx = 0;
11082 }
11083 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11084 {
11085 // report the max possible speed with RSSI scaling
11086 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11087 {
11088 // report the max possible speed
11089 rssidx = 0;
11090 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011091 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011092 {
11093 // report middle speed
11094 rssidx = 1;
11095 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011096 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11097 {
11098 // report middle speed
11099 rssidx = 2;
11100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 else
11102 {
11103 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011104 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 }
11106 }
11107 else
11108 {
11109 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11110 hddLog(VOS_TRACE_LEVEL_ERROR,
11111 "%s: Invalid value for reportMaxLinkSpeed: %u",
11112 __func__, pCfg->reportMaxLinkSpeed);
11113 rssidx = 0;
11114 }
11115
11116 maxRate = 0;
11117
11118 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011119 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11120 OperationalRates, &ORLeng))
11121 {
11122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11123 /*To keep GUI happy*/
11124 return 0;
11125 }
11126
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 for (i = 0; i < ORLeng; i++)
11128 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011129 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 {
11131 /* Validate Rate Set */
11132 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11133 {
11134 currentRate = supported_data_rate[j].supported_rate[rssidx];
11135 break;
11136 }
11137 }
11138 /* Update MAX rate */
11139 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11140 }
11141
11142 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011143 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11144 ExtendedRates, &ERLeng))
11145 {
11146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11147 /*To keep GUI happy*/
11148 return 0;
11149 }
11150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 for (i = 0; i < ERLeng; i++)
11152 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011153 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 {
11155 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11156 {
11157 currentRate = supported_data_rate[j].supported_rate[rssidx];
11158 break;
11159 }
11160 }
11161 /* Update MAX rate */
11162 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11163 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011164 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011165 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011166 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011167 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011168 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011170 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11171 MCSRates, &MCSLeng))
11172 {
11173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11174 /*To keep GUI happy*/
11175 return 0;
11176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011178#ifdef WLAN_FEATURE_11AC
11179 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011180 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011182 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011183 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011184 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011186 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011188 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011190 maxMCSIdx = 7;
11191 }
11192 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11193 {
11194 maxMCSIdx = 8;
11195 }
11196 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11197 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011198 //VHT20 is supporting 0~8
11199 if (rate_flags & eHAL_TX_RATE_VHT20)
11200 maxMCSIdx = 8;
11201 else
11202 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011203 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011204
11205 if (rate_flags & eHAL_TX_RATE_VHT80)
11206 {
11207 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11208 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11209 }
11210 else if (rate_flags & eHAL_TX_RATE_VHT40)
11211 {
11212 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11213 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11214 }
11215 else if (rate_flags & eHAL_TX_RATE_VHT20)
11216 {
11217 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11218 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11219 }
11220
Leo Chang6f8870f2013-03-26 18:11:36 -070011221 maxSpeedMCS = 1;
11222 if (currentRate > maxRate)
11223 {
11224 maxRate = currentRate;
11225 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011226
Leo Chang6f8870f2013-03-26 18:11:36 -070011227 }
11228 else
11229#endif /* WLAN_FEATURE_11AC */
11230 {
11231 if (rate_flags & eHAL_TX_RATE_HT40)
11232 {
11233 rateFlag |= 1;
11234 }
11235 if (rate_flags & eHAL_TX_RATE_SGI)
11236 {
11237 rateFlag |= 2;
11238 }
11239
11240 for (i = 0; i < MCSLeng; i++)
11241 {
11242 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11243 for (j = 0; j < temp; j++)
11244 {
11245 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11246 {
11247 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11248 break;
11249 }
11250 }
11251 if ((j < temp) && (currentRate > maxRate))
11252 {
11253 maxRate = currentRate;
11254 maxSpeedMCS = 1;
11255 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11256 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 }
11258 }
11259 }
11260
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011261 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11262 {
11263 maxRate = myRate;
11264 maxSpeedMCS = 1;
11265 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11266 }
11267
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011269 if (((maxRate < myRate) && (0 == rssidx)) ||
11270 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 {
11272 maxRate = myRate;
11273 if (rate_flags & eHAL_TX_RATE_LEGACY)
11274 {
11275 maxSpeedMCS = 0;
11276 }
11277 else
11278 {
11279 maxSpeedMCS = 1;
11280 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11281 }
11282 }
11283
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011284 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 {
11286 sinfo->txrate.legacy = maxRate;
11287#ifdef LINKSPEED_DEBUG_ENABLED
11288 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11289#endif //LINKSPEED_DEBUG_ENABLED
11290 }
11291 else
11292 {
11293 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011294#ifdef WLAN_FEATURE_11AC
11295 sinfo->txrate.nss = 1;
11296 if (rate_flags & eHAL_TX_RATE_VHT80)
11297 {
11298 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011299 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011300 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011301 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011302 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011303 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11304 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11305 }
11306 else if (rate_flags & eHAL_TX_RATE_VHT20)
11307 {
11308 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11309 }
11310#endif /* WLAN_FEATURE_11AC */
11311 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11312 {
11313 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11314 if (rate_flags & eHAL_TX_RATE_HT40)
11315 {
11316 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11317 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011318 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 if (rate_flags & eHAL_TX_RATE_SGI)
11320 {
11321 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11322 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011323
Jeff Johnson295189b2012-06-20 16:38:30 -070011324#ifdef LINKSPEED_DEBUG_ENABLED
11325 pr_info("Reporting MCS rate %d flags %x\n",
11326 sinfo->txrate.mcs,
11327 sinfo->txrate.flags );
11328#endif //LINKSPEED_DEBUG_ENABLED
11329 }
11330 }
11331 else
11332 {
11333 // report current rate instead of max rate
11334
11335 if (rate_flags & eHAL_TX_RATE_LEGACY)
11336 {
11337 //provide to the UI in units of 100kbps
11338 sinfo->txrate.legacy = myRate;
11339#ifdef LINKSPEED_DEBUG_ENABLED
11340 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11341#endif //LINKSPEED_DEBUG_ENABLED
11342 }
11343 else
11344 {
11345 //must be MCS
11346 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011347#ifdef WLAN_FEATURE_11AC
11348 sinfo->txrate.nss = 1;
11349 if (rate_flags & eHAL_TX_RATE_VHT80)
11350 {
11351 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11352 }
11353 else
11354#endif /* WLAN_FEATURE_11AC */
11355 {
11356 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11357 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 if (rate_flags & eHAL_TX_RATE_SGI)
11359 {
11360 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11361 }
11362 if (rate_flags & eHAL_TX_RATE_HT40)
11363 {
11364 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11365 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011366#ifdef WLAN_FEATURE_11AC
11367 else if (rate_flags & eHAL_TX_RATE_VHT80)
11368 {
11369 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11370 }
11371#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011372#ifdef LINKSPEED_DEBUG_ENABLED
11373 pr_info("Reporting actual MCS rate %d flags %x\n",
11374 sinfo->txrate.mcs,
11375 sinfo->txrate.flags );
11376#endif //LINKSPEED_DEBUG_ENABLED
11377 }
11378 }
11379 sinfo->filled |= STATION_INFO_TX_BITRATE;
11380
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011381 sinfo->tx_packets =
11382 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11383 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11384 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11385 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11386
11387 sinfo->tx_retries =
11388 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11389 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11390 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11391 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11392
11393 sinfo->tx_failed =
11394 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11395 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11396 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11397 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11398
11399 sinfo->filled |=
11400 STATION_INFO_TX_PACKETS |
11401 STATION_INFO_TX_RETRIES |
11402 STATION_INFO_TX_FAILED;
11403
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011404 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11405 TRACE_CODE_HDD_CFG80211_GET_STA,
11406 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011407 EXIT();
11408 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011409}
11410
11411static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011412 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011413{
11414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011415 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011417 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011418
Jeff Johnsone7245742012-09-05 17:12:55 -070011419 ENTER();
11420
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 if (NULL == pAdapter)
11422 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 return -ENODEV;
11425 }
11426
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11428 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11429 pAdapter->sessionId, timeout));
11430
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011432 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011433
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011434 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011435 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11437 "%s: HDD context is not valid", __func__);
11438 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011439 }
11440
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011441 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11442 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11443 (pHddCtx->cfg_ini->fhostArpOffload) &&
11444 (eConnectionState_Associated ==
11445 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11446 {
Amar Singhald53568e2013-09-26 11:03:45 -070011447
11448 hddLog(VOS_TRACE_LEVEL_INFO,
11449 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011450 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011451 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11452 {
11453 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011454 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011455 __func__, vos_status);
11456 }
11457 }
11458
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 /**The get power cmd from the supplicant gets updated by the nl only
11460 *on successful execution of the function call
11461 *we are oppositely mapped w.r.t mode in the driver
11462 **/
11463 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11464
Kiet Lam94fd2922014-06-18 19:12:43 -070011465 if (!mode)
11466 {
11467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11468 "%s: DHCP start indicated through power save", __func__);
11469
11470 pHddCtx->btCoexModeSet = TRUE;
11471 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11472 pAdapter->sessionId);
11473 }
11474 else
11475 {
11476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11477 "%s: DHCP stop indicated through power save", __func__);
11478
11479 pHddCtx->btCoexModeSet = FALSE;
11480 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11481 pAdapter->sessionId);
11482 }
11483
Jeff Johnsone7245742012-09-05 17:12:55 -070011484 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 if (VOS_STATUS_E_FAILURE == vos_status)
11486 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11488 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 return -EINVAL;
11490 }
11491 return 0;
11492}
11493
11494
11495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11496static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11497 struct net_device *netdev,
11498 u8 key_index)
11499{
Jeff Johnsone7245742012-09-05 17:12:55 -070011500 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 return 0;
11502}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011504
11505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11506static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11507 struct net_device *dev,
11508 struct ieee80211_txq_params *params)
11509{
Jeff Johnsone7245742012-09-05 17:12:55 -070011510 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 return 0;
11512}
11513#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11514static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11515 struct ieee80211_txq_params *params)
11516{
Jeff Johnsone7245742012-09-05 17:12:55 -070011517 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 return 0;
11519}
11520#endif //LINUX_VERSION_CODE
11521
11522static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11523 struct net_device *dev, u8 *mac)
11524{
11525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011526 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011527 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011528 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011529 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530
Jeff Johnsone7245742012-09-05 17:12:55 -070011531 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011532
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011533 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011535 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 return -EINVAL;
11537 }
11538
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11540 TRACE_CODE_HDD_CFG80211_DEL_STA,
11541 pAdapter->sessionId, pAdapter->device_mode));
11542
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11544 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011546 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011547 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11549 "%s: HDD context is not valid", __func__);
11550 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011551 }
11552
Jeff Johnson295189b2012-06-20 16:38:30 -070011553 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011555 )
11556 {
11557 if( NULL == mac )
11558 {
11559 v_U16_t i;
11560 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11561 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011562 if ((pAdapter->aStaInfo[i].isUsed) &&
11563 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 {
11565 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11566 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011567 "%s: Delete STA with MAC::"
11568 MAC_ADDRESS_STR,
11569 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011570 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11571 if (VOS_IS_STATUS_SUCCESS(vos_status))
11572 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 }
11574 }
11575 }
11576 else
11577 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011578
11579 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11580 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11581 {
11582 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011583 "%s: Skip this DEL STA as this is not used::"
11584 MAC_ADDRESS_STR,
11585 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011586 return -ENOENT;
11587 }
11588
11589 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11590 {
11591 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011592 "%s: Skip this DEL STA as deauth is in progress::"
11593 MAC_ADDRESS_STR,
11594 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011595 return -ENOENT;
11596 }
11597
11598 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11599
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 hddLog(VOS_TRACE_LEVEL_INFO,
11601 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011602 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011604 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011605
11606 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11607 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11608 {
11609 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11610 hddLog(VOS_TRACE_LEVEL_INFO,
11611 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011612 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011613 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011614 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011615 return -ENOENT;
11616 }
11617
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 }
11619 }
11620
11621 EXIT();
11622
11623 return 0;
11624}
11625
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011626static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11627 struct net_device *dev, u8 *mac, struct station_parameters *params)
11628{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011630 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011631#ifdef FEATURE_WLAN_TDLS
11632 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011633 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011634
11635 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11636 TRACE_CODE_HDD_CFG80211_ADD_STA,
11637 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011638 mask = params->sta_flags_mask;
11639
11640 set = params->sta_flags_set;
11641
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011642#ifdef WLAN_FEATURE_TDLS_DEBUG
11643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11644 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11645 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11646#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011647
11648 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11649 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011650 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011651 }
11652 }
11653#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011654 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011655}
11656
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011657
11658#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011659
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011660static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011661 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011662{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011663 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011664 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011665 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011666 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011668 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011669 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011670 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011671 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11672 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011673
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011675 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011676 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011678 return -EINVAL;
11679 }
11680
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011681 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11682 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011683
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011684 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011685 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11687 "%s: HDD context is not valid", __func__);
11688 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011689 }
11690
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011691 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011692 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011693 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011694
Agarwal Ashish3da95242014-05-21 14:57:17 +053011695 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011696 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011697 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011698 pmksa->bssid, WNI_CFG_BSSID_LEN))
11699 {
11700 /* BSSID matched previous entry. Overwrite it. */
11701 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011702 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011703 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011704 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011706 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011708 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011709 dump_bssid(pmksa->bssid);
11710 dump_pmkid(halHandle, pmksa->pmkid);
11711 break;
11712 }
11713 }
11714
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011715 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011716 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011717
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011718 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719 {
11720 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011721 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011723 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011724 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011725 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011726 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11727 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011728 dump_bssid(pmksa->bssid);
11729 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011730 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011731 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011732 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11733 pHddStaCtx->PMKIDCacheIndex++;
11734 else
11735 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011736 }
11737
11738
11739 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011740 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11741 __func__, pHddStaCtx->PMKIDCacheIndex );
11742
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011743 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011745 pHddStaCtx->PMKIDCache,
11746 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11748 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11749 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011750 return 0;
11751}
11752
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011753static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11754 struct cfg80211_pmksa *pmksa)
11755{
11756 int ret;
11757
11758 vos_ssr_protect(__func__);
11759 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11760 vos_ssr_unprotect(__func__);
11761
11762 return ret;
11763}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011764
Wilson Yang6507c4e2013-10-01 20:11:19 -070011765
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011766static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011767 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011768{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011769 tANI_U32 j=0;
11770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011771 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011772 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011773 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011774 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011775 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011776
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011777 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11778 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011779
11780 /* Validate pAdapter */
11781 if (NULL == pAdapter)
11782 {
11783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11784 return -EINVAL;
11785 }
11786
11787 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11788 status = wlan_hdd_validate_context(pHddCtx);
11789
11790 if (0 != status)
11791 {
11792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11793 "%s: HDD context is not valid", __func__);
11794 return status;
11795 }
11796
11797 /*Retrieve halHandle*/
11798 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011800
11801 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011802 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011803 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011804 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11805 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011806 }
11807
11808 /*find the matching PMKSA entry from j=0 to (index-1),
11809 * and delete the matched one
11810 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011811 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011812 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011813 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011814 pmksa->bssid,
11815 WNI_CFG_BSSID_LEN))
11816 {
11817 /* BSSID matched entry */
11818 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011819 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011820 {
11821 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011822 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11823 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11824 VOS_MAC_ADDR_SIZE);
11825 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11826 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11827 CSR_RSN_PMKID_SIZE);
11828 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011829
11830 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011831 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11832 VOS_MAC_ADDR_SIZE);
11833 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11834 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011835 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011836 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011837 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011838 if (eHAL_STATUS_SUCCESS !=
11839 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011840 {
11841 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011842 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011843 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011844 }
11845
11846 dump_bssid(pmksa->bssid);
11847 dump_pmkid(halHandle,pmksa->pmkid);
11848
11849 break;
11850 }
11851 }
11852
11853 /* we compare all entries,but cannot find matching entry */
11854 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
11855 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011856 hddLog(VOS_TRACE_LEVEL_FATAL,
11857 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
11858 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011859 dump_bssid(pmksa->bssid);
11860 dump_pmkid(halHandle, pmksa->pmkid);
11861 return -EINVAL;
11862 }
Wilson Yangef657d32014-01-15 19:19:23 -080011863 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011864}
11865
Wilson Yang6507c4e2013-10-01 20:11:19 -070011866
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011867static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
11868 struct cfg80211_pmksa *pmksa)
11869{
11870 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011871
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011872 vos_ssr_protect(__func__);
11873 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
11874 vos_ssr_unprotect(__func__);
11875
11876 return ret;
11877
11878}
11879
11880static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011881{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011882 tANI_U32 j=0;
11883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011884 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011885 tHalHandle halHandle;
11886 hdd_context_t *pHddCtx;
11887 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080011888 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011889
11890 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
11891
11892 /* Validate pAdapter */
11893 if (NULL == pAdapter)
11894 {
11895 hddLog(VOS_TRACE_LEVEL_ERROR,
11896 "%s: Invalid Adapter" ,__func__);
11897 return -EINVAL;
11898 }
11899
11900 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11901 status = wlan_hdd_validate_context(pHddCtx);
11902
11903 if (0 != status)
11904 {
11905 hddLog(VOS_TRACE_LEVEL_ERROR,
11906 "%s: HDD context is not valid", __func__);
11907 return status;
11908 }
11909
11910 /*Retrieve halHandle*/
11911 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011912 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011913
11914 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011915 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011916 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053011917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053011918 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011919 }
11920
11921 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011922 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011923 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011924 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011925 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011926 if (eHAL_STATUS_SUCCESS !=
11927 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011928 {
11929 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
11930 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080011931 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011932 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053011933 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011934 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
11935 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
11936 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011937
Agarwal Ashish3da95242014-05-21 14:57:17 +053011938 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080011939 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011940}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011941
11942static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
11943{
11944 int ret;
11945
11946 vos_ssr_protect(__func__);
11947 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
11948 vos_ssr_unprotect(__func__);
11949
11950 return ret;
11951}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011952#endif
11953
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011954#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011955static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011956 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
11957{
11958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11959 hdd_station_ctx_t *pHddStaCtx;
11960
11961 if (NULL == pAdapter)
11962 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011964 return -ENODEV;
11965 }
11966
11967 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11968
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11970 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
11971 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011972 // Added for debug on reception of Re-assoc Req.
11973 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
11974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011975 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011976 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011977 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011978 }
11979
11980#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080011981 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011982 ftie->ie_len);
11983#endif
11984
11985 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011986 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11987 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011988 ftie->ie_len);
11989 return 0;
11990}
11991#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011992
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053011993#ifdef FEATURE_WLAN_SCAN_PNO
11994
11995void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
11996 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
11997{
11998 int ret;
11999 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12000 hdd_context_t *pHddCtx;
12001
Nirav Shah80830bf2013-12-31 16:35:12 +053012002 ENTER();
12003
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012004 if (NULL == pAdapter)
12005 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012007 "%s: HDD adapter is Null", __func__);
12008 return ;
12009 }
12010
12011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12012 if (NULL == pHddCtx)
12013 {
12014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12015 "%s: HDD context is Null!!!", __func__);
12016 return ;
12017 }
12018
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012019 spin_lock(&pHddCtx->schedScan_lock);
12020 if (TRUE == pHddCtx->isWiphySuspended)
12021 {
12022 pHddCtx->isSchedScanUpdatePending = TRUE;
12023 spin_unlock(&pHddCtx->schedScan_lock);
12024 hddLog(VOS_TRACE_LEVEL_INFO,
12025 "%s: Update cfg80211 scan database after it resume", __func__);
12026 return ;
12027 }
12028 spin_unlock(&pHddCtx->schedScan_lock);
12029
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012030 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12031
12032 if (0 > ret)
12033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12034
12035 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12037 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012038}
12039
12040/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012041 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012042 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012043 */
12044static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12045{
12046 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12047 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012048 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012049 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12050 int status = 0;
12051 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12052
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012053 /* The current firmware design does not allow PNO during any
12054 * active sessions. Hence, determine the active sessions
12055 * and return a failure.
12056 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012057 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12058 {
12059 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012060 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012061
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012062 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12063 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12064 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12065 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12066 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12067 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012068 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012069 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012070 }
12071 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12072 pAdapterNode = pNext;
12073 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012074 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012075}
12076
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012077void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12078{
12079 hdd_adapter_t *pAdapter = callbackContext;
12080 hdd_context_t *pHddCtx;
12081
12082 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12083 {
12084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12085 FL("Invalid adapter or adapter has invalid magic"));
12086 return;
12087 }
12088
12089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12090 if (0 != wlan_hdd_validate_context(pHddCtx))
12091 {
12092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12093 FL("HDD context is not valid"));
12094 return;
12095 }
12096
12097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12098 FL("PNO enable response status = %d"), status);
12099
12100 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12101 complete(&pAdapter->pno_comp_var);
12102}
12103
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012104/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012105 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12106 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012107 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012108static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012109 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12110{
12111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12112 tpSirPNOScanReq pPnoRequest = NULL;
12113 hdd_context_t *pHddCtx;
12114 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012115 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012116 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12117 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012118 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12119 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012120 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012121
12122 if (NULL == pAdapter)
12123 {
12124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12125 "%s: HDD adapter is Null", __func__);
12126 return -ENODEV;
12127 }
12128
12129 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012130 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012131
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012132 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012133 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12135 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012136 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012137 }
12138
12139 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12140 if (NULL == hHal)
12141 {
12142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12143 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012144 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012145 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012146
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012147 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012148 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012149 {
12150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12151 "%s: aborting the existing scan is unsuccessfull", __func__);
12152 return -EBUSY;
12153 }
12154
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012155 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012156 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012158 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012159 return -EBUSY;
12160 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012161
c_hpothu37f21312014-04-09 21:49:54 +053012162 if (TRUE == pHddCtx->isPnoEnable)
12163 {
12164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12165 FL("already PNO is enabled"));
12166 return -EBUSY;
12167 }
12168 pHddCtx->isPnoEnable = TRUE;
12169
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012170 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12171 if (NULL == pPnoRequest)
12172 {
12173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12174 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012175 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012176 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012177 }
12178
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012179 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012180 pPnoRequest->enable = 1; /*Enable PNO */
12181 pPnoRequest->ucNetworksCount = request->n_match_sets;
12182
12183 if (( !pPnoRequest->ucNetworksCount ) ||
12184 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12185 {
12186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012187 "%s: Network input is not correct %d Max Network supported is %d",
12188 __func__, pPnoRequest->ucNetworksCount,
12189 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012190 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012191 goto error;
12192 }
12193
12194 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12195 {
12196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012197 "%s: Incorrect number of channels %d",
12198 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012199 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012200 goto error;
12201 }
12202
12203 /* Framework provides one set of channels(all)
12204 * common for all saved profile */
12205 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12206 channels_allowed, &num_channels_allowed))
12207 {
12208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12209 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012210 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012211 goto error;
12212 }
12213 /* Checking each channel against allowed channel list */
12214 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012215 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012216 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012217 char chList [(request->n_channels*5)+1];
12218 int len;
12219 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012220 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012221 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012222 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012223 if (request->channels[i]->hw_value == channels_allowed[indx])
12224 {
12225 valid_ch[num_ch++] = request->channels[i]->hw_value;
12226 len += snprintf(chList+len, 5, "%d ",
12227 request->channels[i]->hw_value);
12228 break ;
12229 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012230 }
12231 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012232 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12233 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012234
12235 /* Filling per profile params */
12236 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12237 {
12238 pPnoRequest->aNetworks[i].ssId.length =
12239 request->match_sets[i].ssid.ssid_len;
12240
12241 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12242 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12243 {
12244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012245 "%s: SSID Len %d is not correct for network %d",
12246 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012247 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012248 goto error;
12249 }
12250
12251 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12252 request->match_sets[i].ssid.ssid,
12253 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12255 "%s: SSID of network %d is %s ", __func__,
12256 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012257 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12258 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12259 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12260
12261 /*Copying list of valid channel into request */
12262 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12263 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12264
12265 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12266 }
12267
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012269 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012270 if ((0 < request->ie_len) && (NULL != request->ie))
12271 {
12272 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12273 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12274 pPnoRequest->us24GProbeTemplateLen);
12275
12276 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12277 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12278 pPnoRequest->us5GProbeTemplateLen);
12279 }
12280
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012281 /* Driver gets only one time interval which is hardcoded in
12282 * supplicant for 10000ms. Taking power consumption into account 6 timers
12283 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12284 * 80,160,320 secs. And number of scan cycle for each timer
12285 * is configurable through INI param gPNOScanTimerRepeatValue.
12286 * If it is set to 0 only one timer will be used and PNO scan cycle
12287 * will be repeated after each interval specified by supplicant
12288 * till PNO is disabled.
12289 */
12290 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12291 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12292 else
12293 pPnoRequest->scanTimers.ucScanTimersCount =
12294 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12295
12296 tempInterval = (request->interval)/1000;
12297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12298 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12299 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12300 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12301 {
12302 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12303 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12304 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12305 tempInterval *= 2;
12306 }
12307 //Repeat last timer until pno disabled.
12308 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12309
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012310 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012311
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012312 INIT_COMPLETION(pAdapter->pno_comp_var);
12313 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12314 pPnoRequest->callbackContext = pAdapter;
12315 pAdapter->pno_req_status = 0;
12316
Nirav Shah80830bf2013-12-31 16:35:12 +053012317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12318 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12319 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12320 pPnoRequest->scanTimers.ucScanTimersCount);
12321
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012322 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12323 pPnoRequest, pAdapter->sessionId,
12324 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12325 if (eHAL_STATUS_SUCCESS != status)
12326 {
12327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012328 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012329 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012330 goto error;
12331 }
12332
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012333 ret = wait_for_completion_timeout(
12334 &pAdapter->pno_comp_var,
12335 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12336 if (0 >= ret)
12337 {
12338 // Did not receive the response for PNO enable in time.
12339 // Assuming the PNO enable was success.
12340 // Returning error from here, because we timeout, results
12341 // in side effect of Wifi (Wifi Setting) not to work.
12342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12343 FL("Timed out waiting for PNO to be Enabled"));
12344 ret = 0;
12345 goto error;
12346 }
12347
12348 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012349 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012350
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012351error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12353 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012354 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012355 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012356 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012357}
12358
12359/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012360 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12361 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012362 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012363static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12364 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12365{
12366 int ret;
12367
12368 vos_ssr_protect(__func__);
12369 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12370 vos_ssr_unprotect(__func__);
12371
12372 return ret;
12373}
12374
12375/*
12376 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12377 * Function to disable PNO
12378 */
12379static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012380 struct net_device *dev)
12381{
12382 eHalStatus status = eHAL_STATUS_FAILURE;
12383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12384 hdd_context_t *pHddCtx;
12385 tHalHandle hHal;
12386 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012387 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012388
12389 ENTER();
12390
12391 if (NULL == pAdapter)
12392 {
12393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12394 "%s: HDD adapter is Null", __func__);
12395 return -ENODEV;
12396 }
12397
12398 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012399
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012400 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012401 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012403 "%s: HDD context is Null", __func__);
12404 return -ENODEV;
12405 }
12406
12407 /* The return 0 is intentional when isLogpInProgress and
12408 * isLoadUnloadInProgress. We did observe a crash due to a return of
12409 * failure in sched_scan_stop , especially for a case where the unload
12410 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12411 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12412 * success. If it returns a failure , then its next invocation due to the
12413 * clean up of the second interface will have the dev pointer corresponding
12414 * to the first one leading to a crash.
12415 */
12416 if (pHddCtx->isLogpInProgress)
12417 {
12418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12419 "%s: LOGP in Progress. Ignore!!!", __func__);
12420 return ret;
12421 }
12422
Mihir Shete18156292014-03-11 15:38:30 +053012423 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012424 {
12425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12426 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12427 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012428 }
12429
12430 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12431 if (NULL == hHal)
12432 {
12433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12434 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012435 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012436 }
12437
12438 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12439 if (NULL == pPnoRequest)
12440 {
12441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12442 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012443 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012444 }
12445
12446 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12447 pPnoRequest->enable = 0; /* Disable PNO */
12448 pPnoRequest->ucNetworksCount = 0;
12449
12450 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12451 pAdapter->sessionId,
12452 NULL, pAdapter);
12453 if (eHAL_STATUS_SUCCESS != status)
12454 {
12455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12456 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012457 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012458 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012459 }
c_hpothu37f21312014-04-09 21:49:54 +053012460 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012461
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012462error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012464 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012465 vos_mem_free(pPnoRequest);
12466
12467 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012468 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012469}
12470
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012471/*
12472 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12473 * NL interface to disable PNO
12474 */
12475static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12476 struct net_device *dev)
12477{
12478 int ret;
12479
12480 vos_ssr_protect(__func__);
12481 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12482 vos_ssr_unprotect(__func__);
12483
12484 return ret;
12485}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012486#endif /*FEATURE_WLAN_SCAN_PNO*/
12487
12488
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012489#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012490#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012491static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12492 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012493 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12494#else
12495static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12496 u8 *peer, u8 action_code, u8 dialog_token,
12497 u16 status_code, const u8 *buf, size_t len)
12498#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012499{
12500
12501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012503 u8 peerMac[6];
12504 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012505 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012506 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012507 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012508#if !(TDLS_MGMT_VERSION2)
12509 u32 peer_capability = 0;
12510#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012511 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012512
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012513 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12514 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12515 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012516 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012519 "Invalid arguments");
12520 return -EINVAL;
12521 }
12522
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012523 if (pHddCtx->isLogpInProgress)
12524 {
12525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12526 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012527 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012528 return -EBUSY;
12529 }
12530
Hoonki Lee27511902013-03-14 18:19:06 -070012531 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012532 {
Hoonki Lee27511902013-03-14 18:19:06 -070012533 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12534 "%s: TDLS mode is disabled OR not enabled in FW."
12535 MAC_ADDRESS_STR " action %d declined.",
12536 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012537 return -ENOTSUPP;
12538 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012539
Hoonki Lee27511902013-03-14 18:19:06 -070012540 /* other than teardown frame, other mgmt frames are not sent if disabled */
12541 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12542 {
12543 /* if tdls_mode is disabled to respond to peer's request */
12544 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12545 {
12546 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12547 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012548 " TDLS mode is disabled. action %d declined.",
12549 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012550
12551 return -ENOTSUPP;
12552 }
12553 }
12554
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012555 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12556 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012557 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012558 {
12559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012560 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012561 " TDLS setup is ongoing. action %d declined.",
12562 __func__, MAC_ADDR_ARRAY(peer), action_code);
12563 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012564 }
12565 }
12566
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012567 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12568 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012569 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012570 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12571 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012572 {
12573 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12574 we return error code at 'add_station()'. Hence we have this
12575 check again in addtion to add_station().
12576 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012577 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012578 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12580 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012581 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12582 __func__, MAC_ADDR_ARRAY(peer), action_code,
12583 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012584 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012585 }
12586 else
12587 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012588 /* maximum reached. tweak to send error code to peer and return
12589 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012590 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12592 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012593 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12594 __func__, MAC_ADDR_ARRAY(peer), status_code,
12595 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012596 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012597 /* fall through to send setup resp with failure status
12598 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012599 }
12600 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012601 else
12602 {
12603 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012604 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012605 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012606 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012608 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12609 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012610 return -EPERM;
12611 }
12612 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012613 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012614 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012615
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012616#ifdef WLAN_FEATURE_TDLS_DEBUG
12617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012618 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012619 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12620 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012621#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012622
Hoonki Leea34dd892013-02-05 22:56:02 -080012623 /*Except teardown responder will not be used so just make 0*/
12624 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012625 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012626 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012627
12628 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012629 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012630
12631 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12632 responder = pTdlsPeer->is_responder;
12633 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012634 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012636 "%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 -070012637 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12638 dialog_token, status_code, len);
12639 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012640 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012641 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012642
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012643 /* For explicit trigger of DIS_REQ come out of BMPS for
12644 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012645 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012646 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12647 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012648 {
12649 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12650 {
12651 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012652 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012653 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12654 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012655 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12656 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012657 }
12658
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012659 /* make sure doesn't call send_mgmt() while it is pending */
12660 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12661 {
12662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012663 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012664 __func__, MAC_ADDR_ARRAY(peer), action_code);
12665 return -EBUSY;
12666 }
12667
12668 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012669 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12670
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012671 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012672 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012673
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012674 if (VOS_STATUS_SUCCESS != status)
12675 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12677 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012678 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012679 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012680 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012681 }
12682
Hoonki Leed37cbb32013-04-20 00:31:14 -070012683 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12684 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12685
12686 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012687 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012689 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012690 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012691 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012692
12693 if (pHddCtx->isLogpInProgress)
12694 {
12695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12696 "%s: LOGP in Progress. Ignore!!!", __func__);
12697 return -EAGAIN;
12698 }
12699
Hoonki Leed37cbb32013-04-20 00:31:14 -070012700 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012701 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012702 }
12703
Gopichand Nakkala05922802013-03-14 12:23:19 -070012704 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012705 {
12706 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012707 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012708 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012709
Hoonki Leea34dd892013-02-05 22:56:02 -080012710 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12711 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012712 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012713 }
12714 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12715 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012716 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012717 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012718
12719 return 0;
12720}
12721
12722static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
12723 u8 *peer, enum nl80211_tdls_operation oper)
12724{
12725 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12726 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012727 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012728 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12731 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12732 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012733 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012734 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012736 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012737 return -EINVAL;
12738 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012739
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012740 status = wlan_hdd_validate_context(pHddCtx);
12741
12742 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012743 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12745 "%s: HDD context is not valid", __func__);
12746 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012747 }
12748
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012749
12750 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012751 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012752 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012754 "TDLS Disabled in INI OR not enabled in FW. "
12755 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012756 return -ENOTSUPP;
12757 }
12758
12759 switch (oper) {
12760 case NL80211_TDLS_ENABLE_LINK:
12761 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012762 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012763 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012764 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012765
Sunil Dutt41de4e22013-11-14 18:09:02 +053012766 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12767
12768 if ( NULL == pTdlsPeer ) {
12769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12770 " (oper %d) not exsting. ignored",
12771 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12772 return -EINVAL;
12773 }
12774
12775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12776 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12777 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12778 "NL80211_TDLS_ENABLE_LINK");
12779
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012780 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12781 {
12782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12783 MAC_ADDRESS_STR " failed",
12784 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12785 return -EINVAL;
12786 }
12787
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012788 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012789 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012790 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012791
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012792 if (0 != wlan_hdd_tdls_get_link_establish_params(
12793 pAdapter, peer,&tdlsLinkEstablishParams)) {
12794 return -EINVAL;
12795 }
12796 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012797
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012798 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12799 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12800 /* Send TDLS peer UAPSD capabilities to the firmware and
12801 * register with the TL on after the response for this operation
12802 * is received .
12803 */
12804 ret = wait_for_completion_interruptible_timeout(
12805 &pAdapter->tdls_link_establish_req_comp,
12806 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12807 if (ret <= 0)
12808 {
12809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12810 "%s: Link Establish Request Faled Status %ld",
12811 __func__, ret);
12812 return -EINVAL;
12813 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012814 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012815 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012816 /* Mark TDLS client Authenticated .*/
12817 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12818 pTdlsPeer->staId,
12819 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012820 if (VOS_STATUS_SUCCESS == status)
12821 {
Hoonki Lee14621352013-04-16 17:51:19 -070012822 if (pTdlsPeer->is_responder == 0)
12823 {
12824 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12825
12826 wlan_hdd_tdls_timer_restart(pAdapter,
12827 &pTdlsPeer->initiatorWaitTimeoutTimer,
12828 WAIT_TIME_TDLS_INITIATOR);
12829 /* suspend initiator TX until it receives direct packet from the
12830 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12831 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12832 &staId, NULL);
12833 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012834 wlan_hdd_tdls_increment_peer_count(pAdapter);
12835 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012836 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012837
12838 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012839 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
12840 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012841 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012842 int ac;
12843 uint8 ucAc[4] = { WLANTL_AC_VO,
12844 WLANTL_AC_VI,
12845 WLANTL_AC_BK,
12846 WLANTL_AC_BE };
12847 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
12848 for(ac=0; ac < 4; ac++)
12849 {
12850 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12851 pTdlsPeer->staId, ucAc[ac],
12852 tlTid[ac], tlTid[ac], 0, 0,
12853 WLANTL_BI_DIR );
12854 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012855 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012856 }
12857
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012858 }
12859 break;
12860 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080012861 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053012862 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12863
12864 if ( NULL == pTdlsPeer ) {
12865 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12866 " (oper %d) not exsting. ignored",
12867 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12868 return -EINVAL;
12869 }
12870
12871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12872 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12873 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12874 "NL80211_TDLS_DISABLE_LINK");
12875
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012876 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080012877 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012878 long status;
12879
12880 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
12881
Lee Hoonkic1262f22013-01-24 21:59:00 -080012882 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
12883 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012884
12885 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
12886 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
12887 if (status <= 0)
12888 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012889 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12891 "%s: Del station failed status %ld",
12892 __func__, status);
12893 return -EPERM;
12894 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012895 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012896 }
12897 else
12898 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12900 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080012901 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012902 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012903 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012904 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053012905 {
12906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12907 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
12908 __func__, MAC_ADDR_ARRAY(peer));
12909
12910 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
12911 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
12912
12913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12914 " %s TDLS External control and Implicit Trigger not enabled ",
12915 __func__);
12916 return -ENOTSUPP;
12917 }
12918
Sunil Dutt41de4e22013-11-14 18:09:02 +053012919
12920 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12921
12922 if ( NULL == pTdlsPeer ) {
12923 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
12924 " peer not exsting",
12925 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053012926 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053012927 }
12928 else {
12929 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
12930 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
12931 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053012932
12933 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
12934 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053012935 break;
12936 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012937 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053012938 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053012939 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053012940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12941 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
12942 __func__, MAC_ADDR_ARRAY(peer));
12943
12944 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
12945 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
12946
12947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12948 " %s TDLS External control and Implicit Trigger not enabled ",
12949 __func__);
12950 return -ENOTSUPP;
12951 }
12952
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053012953 /* To cater the requirement of establishing the TDLS link
12954 * irrespective of the data traffic , get an entry of TDLS peer.
12955 */
12956 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
12957 if (pTdlsPeer == NULL) {
12958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12959 "%s: peer " MAC_ADDRESS_STR " not existing",
12960 __func__, MAC_ADDR_ARRAY(peer));
12961 return -EINVAL;
12962 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053012963
12964 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
12965
12966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12967 " %s TDLS Add Force Peer Failed",
12968 __func__);
12969 return -EINVAL;
12970 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053012971 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053012972 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012973 case NL80211_TDLS_DISCOVERY_REQ:
12974 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12976 "%s: We don't support in-driver setup/teardown/discovery "
12977 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012978 return -ENOTSUPP;
12979 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12981 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012982 return -ENOTSUPP;
12983 }
12984 return 0;
12985}
Chilam NG571c65a2013-01-19 12:27:36 +053012986
12987int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
12988 struct net_device *dev, u8 *peer)
12989{
Arif Hussaina7c8e412013-11-20 11:06:42 -080012990 hddLog(VOS_TRACE_LEVEL_INFO,
12991 "tdls send discover req: "MAC_ADDRESS_STR,
12992 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053012993
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012994#if TDLS_MGMT_VERSION2
12995 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
12996 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
12997#else
Chilam NG571c65a2013-01-19 12:27:36 +053012998 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
12999 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013000#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013001}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013002#endif
13003
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013004#ifdef WLAN_FEATURE_GTK_OFFLOAD
13005/*
13006 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13007 * Callback rountine called upon receiving response for
13008 * get offload info
13009 */
13010void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13011 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13012{
13013
13014 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013015 tANI_U8 tempReplayCounter[8];
13016 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013017
13018 ENTER();
13019
13020 if (NULL == pAdapter)
13021 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013023 "%s: HDD adapter is Null", __func__);
13024 return ;
13025 }
13026
13027 if (NULL == pGtkOffloadGetInfoRsp)
13028 {
13029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13030 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13031 return ;
13032 }
13033
13034 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13035 {
13036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13037 "%s: wlan Failed to get replay counter value",
13038 __func__);
13039 return ;
13040 }
13041
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013042 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13043 /* Update replay counter */
13044 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13045 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13046
13047 {
13048 /* changing from little to big endian since supplicant
13049 * works on big endian format
13050 */
13051 int i;
13052 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13053
13054 for (i = 0; i < 8; i++)
13055 {
13056 tempReplayCounter[7-i] = (tANI_U8)p[i];
13057 }
13058 }
13059
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013060 /* Update replay counter to NL */
13061 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013062 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013063}
13064
13065/*
13066 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
13067 * This function is used to offload GTK rekeying job to the firmware.
13068 */
13069int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13070 struct cfg80211_gtk_rekey_data *data)
13071{
13072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13073 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13074 hdd_station_ctx_t *pHddStaCtx;
13075 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013076 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013077 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013078 eHalStatus status = eHAL_STATUS_FAILURE;
13079
13080 ENTER();
13081
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013082
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013083 if (NULL == pAdapter)
13084 {
13085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13086 "%s: HDD adapter is Null", __func__);
13087 return -ENODEV;
13088 }
13089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13091 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13092 pAdapter->sessionId, pAdapter->device_mode));
13093
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013094 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013096 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13099 "%s: HDD context is not valid", __func__);
13100 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013101 }
13102
13103 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13104 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13105 if (NULL == hHal)
13106 {
13107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13108 "%s: HAL context is Null!!!", __func__);
13109 return -EAGAIN;
13110 }
13111
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013112 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13113 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13114 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13115 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013116 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013117 {
13118 /* changing from big to little endian since driver
13119 * works on little endian format
13120 */
13121 tANI_U8 *p =
13122 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13123 int i;
13124
13125 for (i = 0; i < 8; i++)
13126 {
13127 p[7-i] = data->replay_ctr[i];
13128 }
13129 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013130
13131 if (TRUE == pHddCtx->hdd_wlan_suspended)
13132 {
13133 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013134 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13135 sizeof (tSirGtkOffloadParams));
13136 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013137 pAdapter->sessionId);
13138
13139 if (eHAL_STATUS_SUCCESS != status)
13140 {
13141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13142 "%s: sme_SetGTKOffload failed, returned %d",
13143 __func__, status);
13144 return status;
13145 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13147 "%s: sme_SetGTKOffload successfull", __func__);
13148 }
13149 else
13150 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13152 "%s: wlan not suspended GTKOffload request is stored",
13153 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013154 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013155
13156 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013157}
13158#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
13159
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013160/*
13161 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13162 * This function is used to set access control policy
13163 */
13164static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13165 struct net_device *dev, const struct cfg80211_acl_data *params)
13166{
13167 int i;
13168 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13169 hdd_hostapd_state_t *pHostapdState;
13170 tsap_Config_t *pConfig;
13171 v_CONTEXT_t pVosContext = NULL;
13172 hdd_context_t *pHddCtx;
13173 int status;
13174
13175 ENTER();
13176
13177 if (NULL == pAdapter)
13178 {
13179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13180 "%s: HDD adapter is Null", __func__);
13181 return -ENODEV;
13182 }
13183
13184 if (NULL == params)
13185 {
13186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13187 "%s: params is Null", __func__);
13188 return -EINVAL;
13189 }
13190
13191 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13192 status = wlan_hdd_validate_context(pHddCtx);
13193
13194 if (0 != status)
13195 {
13196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13197 "%s: HDD context is not valid", __func__);
13198 return status;
13199 }
13200
13201 pVosContext = pHddCtx->pvosContext;
13202 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13203
13204 if (NULL == pHostapdState)
13205 {
13206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13207 "%s: pHostapdState is Null", __func__);
13208 return -EINVAL;
13209 }
13210
13211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13212 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13213
13214 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13215 {
13216 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13217
13218 /* default value */
13219 pConfig->num_accept_mac = 0;
13220 pConfig->num_deny_mac = 0;
13221
13222 /**
13223 * access control policy
13224 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13225 * listed in hostapd.deny file.
13226 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13227 * listed in hostapd.accept file.
13228 */
13229 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13230 {
13231 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13232 }
13233 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13234 {
13235 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13236 }
13237 else
13238 {
13239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13240 "%s:Acl Policy : %d is not supported",
13241 __func__, params->acl_policy);
13242 return -ENOTSUPP;
13243 }
13244
13245 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13246 {
13247 pConfig->num_accept_mac = params->n_acl_entries;
13248 for (i = 0; i < params->n_acl_entries; i++)
13249 {
13250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13251 "** Add ACL MAC entry %i in WhiletList :"
13252 MAC_ADDRESS_STR, i,
13253 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13254
13255 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13256 sizeof(qcmacaddr));
13257 }
13258 }
13259 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13260 {
13261 pConfig->num_deny_mac = params->n_acl_entries;
13262 for (i = 0; i < params->n_acl_entries; i++)
13263 {
13264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13265 "** Add ACL MAC entry %i in BlackList :"
13266 MAC_ADDRESS_STR, i,
13267 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13268
13269 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13270 sizeof(qcmacaddr));
13271 }
13272 }
13273
13274 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13275 {
13276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13277 "%s: SAP Set Mac Acl fail", __func__);
13278 return -EINVAL;
13279 }
13280 }
13281 else
13282 {
13283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013284 "%s: Invalid device_mode = %s (%d)",
13285 __func__, hdd_device_modetoString(pAdapter->device_mode),
13286 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013287 return -EINVAL;
13288 }
13289
13290 return 0;
13291}
13292
Leo Chang9056f462013-08-01 19:21:11 -070013293#ifdef WLAN_NL80211_TESTMODE
13294#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013295void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013296(
13297 void *pAdapter,
13298 void *indCont
13299)
13300{
Leo Changd9df8aa2013-09-26 13:32:26 -070013301 tSirLPHBInd *lphbInd;
13302 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013303 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013304
13305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013306 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013307
c_hpothu73f35e62014-04-18 13:40:08 +053013308 if (pAdapter == NULL)
13309 {
13310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13311 "%s: pAdapter is NULL\n",__func__);
13312 return;
13313 }
13314
Leo Chang9056f462013-08-01 19:21:11 -070013315 if (NULL == indCont)
13316 {
13317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013318 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013319 return;
13320 }
13321
c_hpothu73f35e62014-04-18 13:40:08 +053013322 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013323 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013324 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013325 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013326 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013327 GFP_ATOMIC);
13328 if (!skb)
13329 {
13330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13331 "LPHB timeout, NL buffer alloc fail");
13332 return;
13333 }
13334
Leo Changac3ba772013-10-07 09:47:04 -070013335 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013336 {
13337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13338 "WLAN_HDD_TM_ATTR_CMD put fail");
13339 goto nla_put_failure;
13340 }
Leo Changac3ba772013-10-07 09:47:04 -070013341 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013342 {
13343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13344 "WLAN_HDD_TM_ATTR_TYPE put fail");
13345 goto nla_put_failure;
13346 }
Leo Changac3ba772013-10-07 09:47:04 -070013347 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013348 sizeof(tSirLPHBInd), lphbInd))
13349 {
13350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13351 "WLAN_HDD_TM_ATTR_DATA put fail");
13352 goto nla_put_failure;
13353 }
Leo Chang9056f462013-08-01 19:21:11 -070013354 cfg80211_testmode_event(skb, GFP_ATOMIC);
13355 return;
13356
13357nla_put_failure:
13358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13359 "NLA Put fail");
13360 kfree_skb(skb);
13361
13362 return;
13363}
13364#endif /* FEATURE_WLAN_LPHB */
13365
13366static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13367{
13368 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13369 int err = 0;
13370#ifdef FEATURE_WLAN_LPHB
13371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013372 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013373#endif /* FEATURE_WLAN_LPHB */
13374
13375 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13376 if (err)
13377 {
13378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13379 "%s Testmode INV ATTR", __func__);
13380 return err;
13381 }
13382
13383 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13384 {
13385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13386 "%s Testmode INV CMD", __func__);
13387 return -EINVAL;
13388 }
13389
13390 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13391 {
13392#ifdef FEATURE_WLAN_LPHB
13393 /* Low Power Heartbeat configuration request */
13394 case WLAN_HDD_TM_CMD_WLAN_HB:
13395 {
13396 int buf_len;
13397 void *buf;
13398 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013399 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013400
13401 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13402 {
13403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13404 "%s Testmode INV DATA", __func__);
13405 return -EINVAL;
13406 }
13407
13408 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13409 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013410
13411 hb_params_temp =(tSirLPHBReq *)buf;
13412 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13413 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13414 return -EINVAL;
13415
Leo Chang9056f462013-08-01 19:21:11 -070013416 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13417 if (NULL == hb_params)
13418 {
13419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13420 "%s Request Buffer Alloc Fail", __func__);
13421 return -EINVAL;
13422 }
13423
13424 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013425 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13426 hb_params,
13427 wlan_hdd_cfg80211_lphb_ind_handler);
13428 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013429 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13431 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013432 vos_mem_free(hb_params);
13433 }
Leo Chang9056f462013-08-01 19:21:11 -070013434 return 0;
13435 }
13436#endif /* FEATURE_WLAN_LPHB */
13437 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13439 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013440 return -EOPNOTSUPP;
13441 }
13442
13443 return err;
13444}
13445#endif /* CONFIG_NL80211_TESTMODE */
13446
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013447static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13448 struct net_device *dev,
13449 int idx, struct survey_info *survey)
13450{
13451 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13452 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013453 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013454 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013455 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013456 v_S7_t snr,rssi;
13457 int status, i, j, filled = 0;
13458
13459 ENTER();
13460
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013461 if (NULL == pAdapter)
13462 {
13463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13464 "%s: HDD adapter is Null", __func__);
13465 return -ENODEV;
13466 }
13467
13468 if (NULL == wiphy)
13469 {
13470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13471 "%s: wiphy is Null", __func__);
13472 return -ENODEV;
13473 }
13474
13475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13476 status = wlan_hdd_validate_context(pHddCtx);
13477
13478 if (0 != status)
13479 {
13480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13481 "%s: HDD context is not valid", __func__);
13482 return status;
13483 }
13484
Mihir Sheted9072e02013-08-21 17:02:29 +053013485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13486
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013487 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013488 0 != pAdapter->survey_idx ||
13489 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013490 {
13491 /* The survey dump ops when implemented completely is expected to
13492 * return a survey of all channels and the ops is called by the
13493 * kernel with incremental values of the argument 'idx' till it
13494 * returns -ENONET. But we can only support the survey for the
13495 * operating channel for now. survey_idx is used to track
13496 * that the ops is called only once and then return -ENONET for
13497 * the next iteration
13498 */
13499 pAdapter->survey_idx = 0;
13500 return -ENONET;
13501 }
13502
13503 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13504
13505 wlan_hdd_get_snr(pAdapter, &snr);
13506 wlan_hdd_get_rssi(pAdapter, &rssi);
13507
13508 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13509 hdd_wlan_get_freq(channel, &freq);
13510
13511
13512 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13513 {
13514 if (NULL == wiphy->bands[i])
13515 {
13516 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13517 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13518 continue;
13519 }
13520
13521 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13522 {
13523 struct ieee80211_supported_band *band = wiphy->bands[i];
13524
13525 if (band->channels[j].center_freq == (v_U16_t)freq)
13526 {
13527 survey->channel = &band->channels[j];
13528 /* The Rx BDs contain SNR values in dB for the received frames
13529 * while the supplicant expects noise. So we calculate and
13530 * return the value of noise (dBm)
13531 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13532 */
13533 survey->noise = rssi - snr;
13534 survey->filled = SURVEY_INFO_NOISE_DBM;
13535 filled = 1;
13536 }
13537 }
13538 }
13539
13540 if (filled)
13541 pAdapter->survey_idx = 1;
13542 else
13543 {
13544 pAdapter->survey_idx = 0;
13545 return -ENONET;
13546 }
13547
13548 return 0;
13549}
13550
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013551/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013552 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013553 * this is called when cfg80211 driver resume
13554 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13555 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013556int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013557{
13558 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13559 hdd_adapter_t *pAdapter;
13560 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13561 VOS_STATUS status = VOS_STATUS_SUCCESS;
13562
13563 ENTER();
13564
13565 if ( NULL == pHddCtx )
13566 {
13567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13568 "%s: HddCtx validation failed", __func__);
13569 return 0;
13570 }
13571
13572 if (pHddCtx->isLogpInProgress)
13573 {
13574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13575 "%s: LOGP in Progress. Ignore!!!", __func__);
13576 return 0;
13577 }
13578
Mihir Shete18156292014-03-11 15:38:30 +053013579 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013580 {
13581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13582 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13583 return 0;
13584 }
13585
13586 spin_lock(&pHddCtx->schedScan_lock);
13587 pHddCtx->isWiphySuspended = FALSE;
13588 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13589 {
13590 spin_unlock(&pHddCtx->schedScan_lock);
13591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13592 "%s: Return resume is not due to PNO indication", __func__);
13593 return 0;
13594 }
13595 // Reset flag to avoid updatating cfg80211 data old results again
13596 pHddCtx->isSchedScanUpdatePending = FALSE;
13597 spin_unlock(&pHddCtx->schedScan_lock);
13598
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013599
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013600 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13601
13602 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13603 {
13604 pAdapter = pAdapterNode->pAdapter;
13605 if ( (NULL != pAdapter) &&
13606 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13607 {
13608 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013609 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13611 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013612 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013613 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013614 {
13615 /* Acquire wakelock to handle the case where APP's tries to
13616 * suspend immediately after updating the scan results. Whis
13617 * results in app's is in suspended state and not able to
13618 * process the connect request to AP
13619 */
13620 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013621 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013622 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013623
13624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13625 "%s : cfg80211 scan result database updated", __func__);
13626
13627 return 0;
13628
13629 }
13630 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13631 pAdapterNode = pNext;
13632 }
13633
13634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13635 "%s: Failed to find Adapter", __func__);
13636 return 0;
13637}
13638
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013639int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13640{
13641 int ret;
13642
13643 vos_ssr_protect(__func__);
13644 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13645 vos_ssr_unprotect(__func__);
13646
13647 return ret;
13648}
13649
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013650/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013651 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013652 * this is called when cfg80211 driver suspends
13653 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013654int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013655 struct cfg80211_wowlan *wow)
13656{
13657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13658
13659 ENTER();
13660 if (NULL == pHddCtx)
13661 {
13662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13663 "%s: HddCtx validation failed", __func__);
13664 return 0;
13665 }
13666
13667 pHddCtx->isWiphySuspended = TRUE;
13668
13669 EXIT();
13670
13671 return 0;
13672}
13673
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013674int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13675 struct cfg80211_wowlan *wow)
13676{
13677 int ret;
13678
13679 vos_ssr_protect(__func__);
13680 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13681 vos_ssr_unprotect(__func__);
13682
13683 return ret;
13684}
Jeff Johnson295189b2012-06-20 16:38:30 -070013685/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013686static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013687{
13688 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13689 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13690 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13691 .change_station = wlan_hdd_change_station,
13692#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13693 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13694 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13695 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013696#else
13697 .start_ap = wlan_hdd_cfg80211_start_ap,
13698 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13699 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013700#endif
13701 .change_bss = wlan_hdd_cfg80211_change_bss,
13702 .add_key = wlan_hdd_cfg80211_add_key,
13703 .get_key = wlan_hdd_cfg80211_get_key,
13704 .del_key = wlan_hdd_cfg80211_del_key,
13705 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013709 .scan = wlan_hdd_cfg80211_scan,
13710 .connect = wlan_hdd_cfg80211_connect,
13711 .disconnect = wlan_hdd_cfg80211_disconnect,
13712 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13713 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13714 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13715 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13716 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13718 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013719 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13721 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13722 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13723 .set_txq_params = wlan_hdd_set_txq_params,
13724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 .get_station = wlan_hdd_cfg80211_get_station,
13726 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13727 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013728 .add_station = wlan_hdd_cfg80211_add_station,
13729#ifdef FEATURE_WLAN_LFR
13730 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13731 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13732 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13733#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013734#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13735 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13736#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013737#ifdef FEATURE_WLAN_TDLS
13738 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13739 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13740#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013741#ifdef WLAN_FEATURE_GTK_OFFLOAD
13742 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13743#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013744#ifdef FEATURE_WLAN_SCAN_PNO
13745 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13746 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13747#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013748 .resume = wlan_hdd_cfg80211_resume_wlan,
13749 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013750 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013751#ifdef WLAN_NL80211_TESTMODE
13752 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13753#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013754 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013755};
13756