blob: fe5b2decb553ae94a5afca72c15c5b6db63f69fd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530168static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700169{
170 WLAN_CIPHER_SUITE_WEP40,
171 WLAN_CIPHER_SUITE_WEP104,
172 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800173#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700174#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
175 WLAN_CIPHER_SUITE_KRK,
176 WLAN_CIPHER_SUITE_CCMP,
177#else
178 WLAN_CIPHER_SUITE_CCMP,
179#endif
180#ifdef FEATURE_WLAN_WAPI
181 WLAN_CIPHER_SUITE_SMS4,
182#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700183#ifdef WLAN_FEATURE_11W
184 WLAN_CIPHER_SUITE_AES_CMAC,
185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700186};
187
188static inline int is_broadcast_ether_addr(const u8 *addr)
189{
190 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
191 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
192}
193
194static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530195{
Jeff Johnson295189b2012-06-20 16:38:30 -0700196 HDD2GHZCHAN(2412, 1, 0) ,
197 HDD2GHZCHAN(2417, 2, 0) ,
198 HDD2GHZCHAN(2422, 3, 0) ,
199 HDD2GHZCHAN(2427, 4, 0) ,
200 HDD2GHZCHAN(2432, 5, 0) ,
201 HDD2GHZCHAN(2437, 6, 0) ,
202 HDD2GHZCHAN(2442, 7, 0) ,
203 HDD2GHZCHAN(2447, 8, 0) ,
204 HDD2GHZCHAN(2452, 9, 0) ,
205 HDD2GHZCHAN(2457, 10, 0) ,
206 HDD2GHZCHAN(2462, 11, 0) ,
207 HDD2GHZCHAN(2467, 12, 0) ,
208 HDD2GHZCHAN(2472, 13, 0) ,
209 HDD2GHZCHAN(2484, 14, 0) ,
210};
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
213{
214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2437, 6, 0) ,
216 HDD2GHZCHAN(2462, 11, 0) ,
217};
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219static struct ieee80211_channel hdd_channels_5_GHZ[] =
220{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700221 HDD5GHZCHAN(4920, 240, 0) ,
222 HDD5GHZCHAN(4940, 244, 0) ,
223 HDD5GHZCHAN(4960, 248, 0) ,
224 HDD5GHZCHAN(4980, 252, 0) ,
225 HDD5GHZCHAN(5040, 208, 0) ,
226 HDD5GHZCHAN(5060, 212, 0) ,
227 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5180, 36, 0) ,
229 HDD5GHZCHAN(5200, 40, 0) ,
230 HDD5GHZCHAN(5220, 44, 0) ,
231 HDD5GHZCHAN(5240, 48, 0) ,
232 HDD5GHZCHAN(5260, 52, 0) ,
233 HDD5GHZCHAN(5280, 56, 0) ,
234 HDD5GHZCHAN(5300, 60, 0) ,
235 HDD5GHZCHAN(5320, 64, 0) ,
236 HDD5GHZCHAN(5500,100, 0) ,
237 HDD5GHZCHAN(5520,104, 0) ,
238 HDD5GHZCHAN(5540,108, 0) ,
239 HDD5GHZCHAN(5560,112, 0) ,
240 HDD5GHZCHAN(5580,116, 0) ,
241 HDD5GHZCHAN(5600,120, 0) ,
242 HDD5GHZCHAN(5620,124, 0) ,
243 HDD5GHZCHAN(5640,128, 0) ,
244 HDD5GHZCHAN(5660,132, 0) ,
245 HDD5GHZCHAN(5680,136, 0) ,
246 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800247#ifdef FEATURE_WLAN_CH144
248 HDD5GHZCHAN(5720,144, 0) ,
249#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDD5GHZCHAN(5745,149, 0) ,
251 HDD5GHZCHAN(5765,153, 0) ,
252 HDD5GHZCHAN(5785,157, 0) ,
253 HDD5GHZCHAN(5805,161, 0) ,
254 HDD5GHZCHAN(5825,165, 0) ,
255};
256
257static struct ieee80211_rate g_mode_rates[] =
258{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530259 HDD_G_MODE_RATETAB(10, 0x1, 0),
260 HDD_G_MODE_RATETAB(20, 0x2, 0),
261 HDD_G_MODE_RATETAB(55, 0x4, 0),
262 HDD_G_MODE_RATETAB(110, 0x8, 0),
263 HDD_G_MODE_RATETAB(60, 0x10, 0),
264 HDD_G_MODE_RATETAB(90, 0x20, 0),
265 HDD_G_MODE_RATETAB(120, 0x40, 0),
266 HDD_G_MODE_RATETAB(180, 0x80, 0),
267 HDD_G_MODE_RATETAB(240, 0x100, 0),
268 HDD_G_MODE_RATETAB(360, 0x200, 0),
269 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271};
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273static struct ieee80211_rate a_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
283};
284
285static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
286{
287 .channels = hdd_channels_2_4_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
289 .band = IEEE80211_BAND_2GHZ,
290 .bitrates = g_mode_rates,
291 .n_bitrates = g_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
297 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
298 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
299 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
300 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
301 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
302};
303
Jeff Johnson295189b2012-06-20 16:38:30 -0700304static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
305{
306 .channels = hdd_social_channels_2_4_GHZ,
307 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
308 .band = IEEE80211_BAND_2GHZ,
309 .bitrates = g_mode_rates,
310 .n_bitrates = g_mode_rates_size,
311 .ht_cap.ht_supported = 1,
312 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
313 | IEEE80211_HT_CAP_GRN_FLD
314 | IEEE80211_HT_CAP_DSSSCCK40
315 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
316 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
317 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
318 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
319 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
320 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
321};
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
324{
325 .channels = hdd_channels_5_GHZ,
326 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
327 .band = IEEE80211_BAND_5GHZ,
328 .bitrates = a_mode_rates,
329 .n_bitrates = a_mode_rates_size,
330 .ht_cap.ht_supported = 1,
331 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
332 | IEEE80211_HT_CAP_GRN_FLD
333 | IEEE80211_HT_CAP_DSSSCCK40
334 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
335 | IEEE80211_HT_CAP_SGI_40
336 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
337 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
338 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
339 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
340 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
341 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
342};
343
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530344/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 TX/RX direction for each kind of interface */
346static const struct ieee80211_txrx_stypes
347wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
348 [NL80211_IFTYPE_STATION] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
427/* By default, only single channel concurrency is allowed */
428static struct ieee80211_iface_combination
429wlan_hdd_iface_combination = {
430 .limits = wlan_hdd_iface_limit,
431 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800432 /*
433 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
434 * and p2p0 interfaces during driver init
435 * Some vendors create separate interface for P2P operations.
436 * wlan0: STA interface
437 * p2p0: P2P Device interface, action frames goes
438 * through this interface.
439 * p2p-xx: P2P interface, After GO negotiation this interface is
440 * created for p2p operations(GO/CLIENT interface).
441 */
442 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800443 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
444 .beacon_int_infra_match = false,
445};
446#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800447
Jeff Johnson295189b2012-06-20 16:38:30 -0700448static struct cfg80211_ops wlan_hdd_cfg80211_ops;
449
450/* Data rate 100KBPS based on IE Index */
451struct index_data_rate_type
452{
453 v_U8_t beacon_rate_index;
454 v_U16_t supported_rate[4];
455};
456
457/* 11B, 11G Rate table include Basic rate and Extended rate
458 The IDX field is the rate index
459 The HI field is the rate when RSSI is strong or being ignored
460 (in this case we report actual rate)
461 The MID field is the rate when RSSI is moderate
462 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
463 The LO field is the rate when RSSI is low
464 (in this case we don't report rates, actual current rate used)
465 */
466static const struct
467{
468 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700469 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700470} supported_data_rate[] =
471{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700472/* IDX HI HM LM LO (RSSI-based index */
473 {2, { 10, 10, 10, 0}},
474 {4, { 20, 20, 10, 0}},
475 {11, { 55, 20, 10, 0}},
476 {12, { 60, 55, 20, 0}},
477 {18, { 90, 55, 20, 0}},
478 {22, {110, 55, 20, 0}},
479 {24, {120, 90, 60, 0}},
480 {36, {180, 120, 60, 0}},
481 {44, {220, 180, 60, 0}},
482 {48, {240, 180, 90, 0}},
483 {66, {330, 180, 90, 0}},
484 {72, {360, 240, 90, 0}},
485 {96, {480, 240, 120, 0}},
486 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700487};
488
489/* MCS Based rate table */
490static struct index_data_rate_type supported_mcs_rate[] =
491{
492/* MCS L20 L40 S20 S40 */
493 {0, {65, 135, 72, 150}},
494 {1, {130, 270, 144, 300}},
495 {2, {195, 405, 217, 450}},
496 {3, {260, 540, 289, 600}},
497 {4, {390, 810, 433, 900}},
498 {5, {520, 1080, 578, 1200}},
499 {6, {585, 1215, 650, 1350}},
500 {7, {650, 1350, 722, 1500}}
501};
502
Leo Chang6f8870f2013-03-26 18:11:36 -0700503#ifdef WLAN_FEATURE_11AC
504
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530505#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700506
507struct index_vht_data_rate_type
508{
509 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510 v_U16_t supported_VHT80_rate[2];
511 v_U16_t supported_VHT40_rate[2];
512 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700513};
514
515typedef enum
516{
517 DATA_RATE_11AC_MAX_MCS_7,
518 DATA_RATE_11AC_MAX_MCS_8,
519 DATA_RATE_11AC_MAX_MCS_9,
520 DATA_RATE_11AC_MAX_MCS_NA
521} eDataRate11ACMaxMcs;
522
523/* MCS Based VHT rate table */
524static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
525{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530526/* MCS L80 S80 L40 S40 L20 S40*/
527 {0, {293, 325}, {135, 150}, {65, 72}},
528 {1, {585, 650}, {270, 300}, {130, 144}},
529 {2, {878, 975}, {405, 450}, {195, 217}},
530 {3, {1170, 1300}, {540, 600}, {260, 289}},
531 {4, {1755, 1950}, {810, 900}, {390, 433}},
532 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
533 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
534 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
535 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
536 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700537};
538#endif /* WLAN_FEATURE_11AC */
539
Jeff Johnson295189b2012-06-20 16:38:30 -0700540extern struct net_device_ops net_ops_struct;
541
Leo Chang9056f462013-08-01 19:21:11 -0700542#ifdef WLAN_NL80211_TESTMODE
543enum wlan_hdd_tm_attr
544{
545 WLAN_HDD_TM_ATTR_INVALID = 0,
546 WLAN_HDD_TM_ATTR_CMD = 1,
547 WLAN_HDD_TM_ATTR_DATA = 2,
548 WLAN_HDD_TM_ATTR_TYPE = 3,
549 /* keep last */
550 WLAN_HDD_TM_ATTR_AFTER_LAST,
551 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
552};
553
554enum wlan_hdd_tm_cmd
555{
556 WLAN_HDD_TM_CMD_WLAN_HB = 1,
557};
558
559#define WLAN_HDD_TM_DATA_MAX_LEN 5000
560
561static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
562{
563 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
564 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
565 .len = WLAN_HDD_TM_DATA_MAX_LEN },
566};
567#endif /* WLAN_NL80211_TESTMODE */
568
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800569#ifdef FEATURE_WLAN_CH_AVOID
570/*
571 * FUNCTION: wlan_hdd_send_avoid_freq_event
572 * This is called when wlan driver needs to send vendor specific
573 * avoid frequency range event to userspace
574 */
575int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
576 tHddAvoidFreqList *pAvoidFreqList)
577{
578 struct sk_buff *vendor_event;
579
580 ENTER();
581
582 if (!pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
585 "%s: HDD context is null", __func__);
586 return -1;
587 }
588
589 if (!pAvoidFreqList)
590 {
591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
592 "%s: pAvoidFreqList is null", __func__);
593 return -1;
594 }
595
596 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
597 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530598 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800599 GFP_KERNEL);
600 if (!vendor_event)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: cfg80211_vendor_event_alloc failed", __func__);
604 return -1;
605 }
606
607 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
608 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
609
610 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
611
612 EXIT();
613 return 0;
614}
615#endif /* FEATURE_WLAN_CH_AVOID */
616
Sunil Duttc69bccb2014-05-26 21:30:20 +0530617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
618
619static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
620 struct sk_buff *vendor_event)
621{
622 if (nla_put_u8(vendor_event,
623 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
624 stats->rate.preamble) ||
625 nla_put_u8(vendor_event,
626 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
627 stats->rate.nss) ||
628 nla_put_u8(vendor_event,
629 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
630 stats->rate.bw) ||
631 nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
633 stats->rate.rateMcsIdx) ||
634 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
635 stats->rate.bitrate ) ||
636 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
637 stats->txMpdu ) ||
638 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
639 stats->rxMpdu ) ||
640 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
641 stats->mpduLost ) ||
642 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
643 stats->retries) ||
644 nla_put_u32(vendor_event,
645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
646 stats->retriesShort ) ||
647 nla_put_u32(vendor_event,
648 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
649 stats->retriesLong))
650 {
651 hddLog(VOS_TRACE_LEVEL_ERROR,
652 FL("QCA_WLAN_VENDOR_ATTR put fail"));
653 return FALSE;
654 }
655 return TRUE;
656}
657
658static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
659 struct sk_buff *vendor_event)
660{
661 u32 i = 0;
662 struct nlattr *rateInfo;
663 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
664 stats->type) ||
665 nla_put(vendor_event,
666 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
667 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
668 nla_put_u32(vendor_event,
669 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
670 stats->capabilities) ||
671 nla_put_u32(vendor_event,
672 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
673 stats->numRate))
674 {
675 hddLog(VOS_TRACE_LEVEL_ERROR,
676 FL("QCA_WLAN_VENDOR_ATTR put fail"));
677 goto error;
678 }
679
680 rateInfo = nla_nest_start(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
682 for (i = 0; i < stats->numRate; i++)
683 {
684 struct nlattr *rates;
685 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
686 stats->rateStats +
687 (i * sizeof(tSirWifiRateStat)));
688 rates = nla_nest_start(vendor_event, i);
689
690 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR,
693 FL("QCA_WLAN_VENDOR_ATTR put fail"));
694 return FALSE;
695 }
696 nla_nest_end(vendor_event, rates);
697 }
698 nla_nest_end(vendor_event, rateInfo);
699
700 return TRUE;
701error:
702 return FALSE;
703}
704
705static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
706 struct sk_buff *vendor_event)
707{
708 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
709 stats->ac ) ||
710 nla_put_u32(vendor_event,
711 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
712 stats->txMpdu ) ||
713 nla_put_u32(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
715 stats->rxMpdu ) ||
716 nla_put_u32(vendor_event,
717 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
718 stats->txMcast ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
721 stats->rxMcast ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
724 stats->rxAmpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
727 stats->txAmpdu ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
730 stats->mpduLost )||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
733 stats->retries ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
736 stats->retriesShort ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
739 stats->retriesLong ) ||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
742 stats->contentionTimeMin ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
745 stats->contentionTimeMax ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
748 stats->contentionTimeAvg ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
751 stats->contentionNumSamples ))
752 {
753 hddLog(VOS_TRACE_LEVEL_ERROR,
754 FL("QCA_WLAN_VENDOR_ATTR put fail") );
755 return FALSE;
756 }
757 return TRUE;
758}
759
760static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
761 struct sk_buff *vendor_event)
762{
763 if (nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
765 nla_put(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
767 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
770 stats->state ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
773 stats->roaming ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
776 stats->capabilities ) ||
777 nla_put(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
779 strlen(stats->ssid), stats->ssid) ||
780 nla_put(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
782 WNI_CFG_BSSID_LEN, stats->bssid) ||
783 nla_put(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
785 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
788 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
789 )
790 {
791 hddLog(VOS_TRACE_LEVEL_ERROR,
792 FL("QCA_WLAN_VENDOR_ATTR put fail") );
793 return FALSE;
794 }
795 return TRUE;
796}
797
798static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
799 struct sk_buff *vendor_event)
800{
801 int i = 0;
802 struct nlattr *wmmInfo;
803 if (FALSE == put_wifi_interface_info(
804 &pWifiIfaceStat->info,
805 vendor_event))
806 {
807 hddLog(VOS_TRACE_LEVEL_ERROR,
808 FL("QCA_WLAN_VENDOR_ATTR put fail") );
809 return FALSE;
810
811 }
812
813 if (nla_put_u32(vendor_event,
814 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
815 pWifiIfaceStat->beaconRx) ||
816 nla_put_u32(vendor_event,
817 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
818 pWifiIfaceStat->mgmtRx) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
821 pWifiIfaceStat->mgmtActionRx) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
824 pWifiIfaceStat->mgmtActionTx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
827 pWifiIfaceStat->rssiMgmt) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
830 pWifiIfaceStat->rssiData) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
833 pWifiIfaceStat->rssiAck))
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,
836 FL("QCA_WLAN_VENDOR_ATTR put fail"));
837 return FALSE;
838 }
839
840 wmmInfo = nla_nest_start(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
842 for (i = 0; i < WIFI_AC_MAX; i++)
843 {
844 struct nlattr *wmmStats;
845 wmmStats = nla_nest_start(vendor_event, i);
846 if (FALSE == put_wifi_wmm_ac_stat(
847 &pWifiIfaceStat->AccessclassStats[i],
848 vendor_event))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
852 return FALSE;
853 }
854
855 nla_nest_end(vendor_event, wmmStats);
856 }
857 nla_nest_end(vendor_event, wmmInfo);
858 return TRUE;
859}
860
861static tSirWifiInterfaceMode
862 hdd_map_device_to_ll_iface_mode ( int deviceMode )
863{
864 switch (deviceMode)
865 {
866 case WLAN_HDD_INFRA_STATION:
867 return WIFI_INTERFACE_STA;
868 case WLAN_HDD_SOFTAP:
869 return WIFI_INTERFACE_SOFTAP;
870 case WLAN_HDD_P2P_CLIENT:
871 return WIFI_INTERFACE_P2P_CLIENT;
872 case WLAN_HDD_P2P_GO:
873 return WIFI_INTERFACE_P2P_GO;
874 case WLAN_HDD_IBSS:
875 return WIFI_INTERFACE_IBSS;
876 default:
877 /* Return Interface Mode as STA for all the unsupported modes */
878 return WIFI_INTERFACE_STA;
879 }
880}
881
882static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
883 tpSirWifiInterfaceInfo pInfo)
884{
885 v_U8_t *staMac = NULL;
886 hdd_station_ctx_t *pHddStaCtx;
887 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
888 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
889
890 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
891
892 vos_mem_copy(pInfo->macAddr,
893 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
894
895 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
896 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
897 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
898 {
899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
900 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
901 {
902 pInfo->state = WIFI_DISCONNECTED;
903 }
904 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
905 {
906 hddLog(VOS_TRACE_LEVEL_ERROR,
907 "%s: Session ID %d, Connection is in progress", __func__,
908 pAdapter->sessionId);
909 pInfo->state = WIFI_ASSOCIATING;
910 }
911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
913 {
914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: client " MAC_ADDRESS_STR
917 " is in the middle of WPS/EAPOL exchange.", __func__,
918 MAC_ADDR_ARRAY(staMac));
919 pInfo->state = WIFI_AUTHENTICATING;
920 }
921 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
922 {
923 pInfo->state = WIFI_ASSOCIATED;
924 vos_mem_copy(pInfo->bssid,
925 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
926 vos_mem_copy(pInfo->ssid,
927 pHddStaCtx->conn_info.SSID.SSID.ssId,
928 pHddStaCtx->conn_info.SSID.SSID.length);
929 //NULL Terminate the string.
930 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
931 }
932 }
933 vos_mem_copy(pInfo->countryStr,
934 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
935
936 vos_mem_copy(pInfo->apCountryStr,
937 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
938
939 return TRUE;
940}
941
942/*
943 * hdd_link_layer_process_peer_stats () - This function is called after
944 * receiving Link Layer Peer statistics from FW.This function converts
945 * the firmware data to the NL data and sends the same to the kernel/upper
946 * layers.
947 */
948static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
949 v_VOID_t *pData)
950{
951 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
952 tpSirWifiRateStat pWifiRateStat;
953 tpSirWifiPeerStat pWifiPeerStat;
954 tpSirWifiPeerInfo pWifiPeerInfo;
955 struct nlattr *peerInfo;
956 struct sk_buff *vendor_event;
957 int status, i;
958
959 status = wlan_hdd_validate_context(pHddCtx);
960 if (0 != status)
961 {
962 hddLog(VOS_TRACE_LEVEL_ERROR,
963 FL("HDD context is not valid") );
964 return;
965 }
966
967 pWifiPeerStat = (tpSirWifiPeerStat) pData;
968
969 hddLog(VOS_TRACE_LEVEL_INFO,
970 "LL_STATS_PEER_ALL : numPeers %u",
971 pWifiPeerStat->numPeers);
972 {
973 for (i = 0; i < pWifiPeerStat->numPeers; i++)
974 {
975 pWifiPeerInfo = (tpSirWifiPeerInfo)
976 ((uint8 *)pWifiPeerStat->peerInfo +
977 ( i * sizeof(tSirWifiPeerInfo)));
978
979 hddLog(VOS_TRACE_LEVEL_INFO,
980 " %d) LL_STATS Channel Stats "
981 " Peer Type %u "
982 " peerMacAddress %pM "
983 " capabilities 0x%x "
984 " numRate %u ",
985 i,
986 pWifiPeerInfo->type,
987 pWifiPeerInfo->peerMacAddress,
988 pWifiPeerInfo->capabilities,
989 pWifiPeerInfo->numRate);
990 {
991 int j;
992 for (j = 0; j < pWifiPeerInfo->numRate; j++)
993 {
994 pWifiRateStat = (tpSirWifiRateStat)
995 ((tANI_U8 *) pWifiPeerInfo->rateStats +
996 ( j * sizeof(tSirWifiRateStat)));
997
998 hddLog(VOS_TRACE_LEVEL_INFO,
999 " peer Rate Stats "
1000 " preamble %u "
1001 " nss %u "
1002 " bw %u "
1003 " rateMcsIdx %u "
1004 " reserved %u "
1005 " bitrate %u "
1006 " txMpdu %u "
1007 " rxMpdu %u "
1008 " mpduLost %u "
1009 " retries %u "
1010 " retriesShort %u "
1011 " retriesLong %u",
1012 pWifiRateStat->rate.preamble,
1013 pWifiRateStat->rate.nss,
1014 pWifiRateStat->rate.bw,
1015 pWifiRateStat->rate.rateMcsIdx,
1016 pWifiRateStat->rate.reserved,
1017 pWifiRateStat->rate.bitrate,
1018 pWifiRateStat->txMpdu,
1019 pWifiRateStat->rxMpdu,
1020 pWifiRateStat->mpduLost,
1021 pWifiRateStat->retries,
1022 pWifiRateStat->retriesShort,
1023 pWifiRateStat->retriesLong);
1024 }
1025 }
1026 }
1027 }
1028
1029 /*
1030 * Allocate a size of 4096 for the peer stats comprising
1031 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1032 * sizeof (tSirWifiRateStat).Each field is put with an
1033 * NL attribute.The size of 4096 is considered assuming
1034 * that number of rates shall not exceed beyond 50 with
1035 * the sizeof (tSirWifiRateStat) being 32.
1036 */
1037 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1038 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1039 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1040 GFP_KERNEL);
1041 if (!vendor_event)
1042 {
1043 hddLog(VOS_TRACE_LEVEL_ERROR,
1044 "%s: cfg80211_vendor_event_alloc failed",
1045 __func__);
1046 return;
1047 }
1048 if (nla_put_u32(vendor_event,
1049 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1050 pWifiPeerStat->numPeers))
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1054 kfree_skb(vendor_event);
1055 return;
1056 }
1057
1058 peerInfo = nla_nest_start(vendor_event,
1059 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1060
1061 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1062 pWifiPeerStat->peerInfo);
1063
1064 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1065 {
1066 struct nlattr *peers = nla_nest_start(vendor_event, i);
1067 int numRate = pWifiPeerInfo->numRate;
1068
1069 if (FALSE == put_wifi_peer_info(
1070 pWifiPeerInfo, vendor_event))
1071 {
1072 hddLog(VOS_TRACE_LEVEL_ERROR,
1073 "%s: put_wifi_peer_info put fail", __func__);
1074 kfree_skb(vendor_event);
1075 return;
1076 }
1077
1078 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1079 pWifiPeerStat->peerInfo +
1080 (i * sizeof(tSirWifiPeerInfo)) +
1081 (numRate * sizeof (tSirWifiRateStat)));
1082 nla_nest_end(vendor_event, peers);
1083 }
1084 nla_nest_end(vendor_event, peerInfo);
1085 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1086}
1087
1088/*
1089 * hdd_link_layer_process_iface_stats () - This function is called after
1090 * receiving Link Layer Interface statistics from FW.This function converts
1091 * the firmware data to the NL data and sends the same to the kernel/upper
1092 * layers.
1093 */
1094static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1095 v_VOID_t *pData)
1096{
1097 tpSirWifiIfaceStat pWifiIfaceStat;
1098 struct sk_buff *vendor_event;
1099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1100 int status;
1101
1102 status = wlan_hdd_validate_context(pHddCtx);
1103 if (0 != status)
1104 {
1105 hddLog(VOS_TRACE_LEVEL_ERROR,
1106 FL("HDD context is not valid") );
1107 return;
1108 }
1109 /*
1110 * Allocate a size of 4096 for the interface stats comprising
1111 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1112 * assuming that all these fit with in the limit.Please take
1113 * a call on the limit based on the data requirements on
1114 * interface statistics.
1115 */
1116 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1117 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1118 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1119 GFP_KERNEL);
1120 if (!vendor_event)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR,
1123 FL("cfg80211_vendor_event_alloc failed") );
1124 return;
1125 }
1126
1127 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1128
1129 hddLog(VOS_TRACE_LEVEL_INFO,
1130 "WMI_LINK_STATS_IFACE Data");
1131
1132 hddLog(VOS_TRACE_LEVEL_INFO,
1133 "LL_STATS_IFACE: "
1134 " Mode %u "
1135 " MAC %pM "
1136 " State %u "
1137 " Roaming %u "
1138 " capabilities 0x%x "
1139 " SSID %s "
1140 " BSSID %pM",
1141 pWifiIfaceStat->info.mode,
1142 pWifiIfaceStat->info.macAddr,
1143 pWifiIfaceStat->info.state,
1144 pWifiIfaceStat->info.roaming,
1145 pWifiIfaceStat->info.capabilities,
1146 pWifiIfaceStat->info.ssid,
1147 pWifiIfaceStat->info.bssid);
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 " AP country str: %c%c%c",
1151 pWifiIfaceStat->info.apCountryStr[0],
1152 pWifiIfaceStat->info.apCountryStr[1],
1153 pWifiIfaceStat->info.apCountryStr[2]);
1154
1155
1156 hddLog(VOS_TRACE_LEVEL_INFO,
1157 " Country Str Association: %c%c%c",
1158 pWifiIfaceStat->info.countryStr[0],
1159 pWifiIfaceStat->info.countryStr[1],
1160 pWifiIfaceStat->info.countryStr[2]);
1161
1162 hddLog(VOS_TRACE_LEVEL_INFO,
1163 " beaconRx %u "
1164 " mgmtRx %u "
1165 " mgmtActionRx %u "
1166 " mgmtActionTx %u "
1167 " rssiMgmt %u "
1168 " rssiData %u "
1169 " rssiAck %u",
1170 pWifiIfaceStat->beaconRx,
1171 pWifiIfaceStat->mgmtRx,
1172 pWifiIfaceStat->mgmtActionRx,
1173 pWifiIfaceStat->mgmtActionTx,
1174 pWifiIfaceStat->rssiMgmt,
1175 pWifiIfaceStat->rssiData,
1176 pWifiIfaceStat->rssiAck );
1177
1178
1179 {
1180 int i;
1181 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_INFO,
1184
1185 " %d) LL_STATS IFACE: "
1186 " ac: %u txMpdu: %u "
1187 " rxMpdu: %u txMcast: %u "
1188 " rxMcast: %u rxAmpdu: %u "
1189 " txAmpdu: %u mpduLost: %u "
1190 " retries: %u retriesShort: %u "
1191 " retriesLong: %u contentionTimeMin: %u "
1192 " contentionTimeMax: %u contentionTimeAvg: %u "
1193 " contentionNumSamples: %u",
1194 i,
1195 pWifiIfaceStat->AccessclassStats[i].ac,
1196 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1197 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1198 pWifiIfaceStat->AccessclassStats[i].txMcast,
1199 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1200 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1201 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1202 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1203 pWifiIfaceStat->AccessclassStats[i].retries,
1204 pWifiIfaceStat->
1205 AccessclassStats[i].retriesShort,
1206 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1207 pWifiIfaceStat->
1208 AccessclassStats[i].contentionTimeMin,
1209 pWifiIfaceStat->
1210 AccessclassStats[i].contentionTimeMax,
1211 pWifiIfaceStat->
1212 AccessclassStats[i].contentionTimeAvg,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].contentionNumSamples);
1215
1216 }
1217 }
1218
1219 if (FALSE == hdd_get_interface_info( pAdapter,
1220 &pWifiIfaceStat->info))
1221 {
1222 hddLog(VOS_TRACE_LEVEL_ERROR,
1223 FL("hdd_get_interface_info get fail") );
1224 kfree_skb(vendor_event);
1225 return;
1226 }
1227
1228 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1229 vendor_event))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("put_wifi_iface_stats fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1237}
1238
1239/*
1240 * hdd_link_layer_process_radio_stats () - This function is called after
1241 * receiving Link Layer Radio statistics from FW.This function converts
1242 * the firmware data to the NL data and sends the same to the kernel/upper
1243 * layers.
1244 */
1245static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1246 v_VOID_t *pData)
1247{
1248 int status, i;
1249 tpSirWifiRadioStat pWifiRadioStat;
1250 tpSirWifiChannelStats pWifiChannelStats;
1251 struct sk_buff *vendor_event;
1252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1253 struct nlattr *chList;
1254
1255 status = wlan_hdd_validate_context(pHddCtx);
1256 if (0 != status)
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("HDD context is not valid") );
1260 return;
1261 }
1262 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1263
1264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 "LL_STATS_RADIO"
1266 " radio is %d onTime is %u "
1267 " txTime is %u rxTime is %u "
1268 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301269 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 " onTimePnoScan is %u onTimeHs20 is %u "
1271 " numChannels is %u",
1272 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1273 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1274 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301275 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301276 pWifiRadioStat->onTimeRoamScan,
1277 pWifiRadioStat->onTimePnoScan,
1278 pWifiRadioStat->onTimeHs20,
1279 pWifiRadioStat->numChannels);
1280 /*
1281 * Allocate a size of 4096 for the Radio stats comprising
1282 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1283 * (tSirWifiChannelStats).Each channel data is put with an
1284 * NL attribute.The size of 4096 is considered assuming that
1285 * number of channels shall not exceed beyond 60 with the
1286 * sizeof (tSirWifiChannelStats) being 24 bytes.
1287 */
1288
1289 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1290 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1291 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1292 GFP_KERNEL);
1293
1294 if (!vendor_event)
1295 {
1296 hddLog(VOS_TRACE_LEVEL_ERROR,
1297 FL("cfg80211_vendor_event_alloc failed") );
1298 return;
1299 }
1300
1301 if (nla_put_u32(vendor_event,
1302 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1303 pWifiRadioStat->radio) ||
1304 nla_put_u32(vendor_event,
1305 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1306 pWifiRadioStat->onTime) ||
1307 nla_put_u32(vendor_event,
1308 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1309 pWifiRadioStat->txTime) ||
1310 nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1312 pWifiRadioStat->rxTime) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1315 pWifiRadioStat->onTimeScan) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1318 pWifiRadioStat->onTimeNbd) ||
1319 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1321 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1324 pWifiRadioStat->onTimeRoamScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1327 pWifiRadioStat->onTimePnoScan) ||
1328 nla_put_u32(vendor_event,
1329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1330 pWifiRadioStat->onTimeHs20) ||
1331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1333 pWifiRadioStat->numChannels))
1334 {
1335 hddLog(VOS_TRACE_LEVEL_ERROR,
1336 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1337 kfree_skb(vendor_event);
1338 return ;
1339 }
1340
1341 chList = nla_nest_start(vendor_event,
1342 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1343 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1344 {
1345 struct nlattr *chInfo;
1346
1347 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1348 pWifiRadioStat->channels +
1349 (i * sizeof(tSirWifiChannelStats)));
1350
1351 hddLog(VOS_TRACE_LEVEL_INFO,
1352 " %d) Channel Info"
1353 " width is %u "
1354 " CenterFreq %u "
1355 " CenterFreq0 %u "
1356 " CenterFreq1 %u "
1357 " onTime %u "
1358 " ccaBusyTime %u",
1359 i,
1360 pWifiChannelStats->channel.width,
1361 pWifiChannelStats->channel.centerFreq,
1362 pWifiChannelStats->channel.centerFreq0,
1363 pWifiChannelStats->channel.centerFreq1,
1364 pWifiChannelStats->onTime,
1365 pWifiChannelStats->ccaBusyTime);
1366
1367
1368 chInfo = nla_nest_start(vendor_event, i);
1369
1370 if (nla_put_u32(vendor_event,
1371 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1372 pWifiChannelStats->channel.width) ||
1373 nla_put_u32(vendor_event,
1374 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1375 pWifiChannelStats->channel.centerFreq) ||
1376 nla_put_u32(vendor_event,
1377 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1378 pWifiChannelStats->channel.centerFreq0) ||
1379 nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1381 pWifiChannelStats->channel.centerFreq1) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1384 pWifiChannelStats->onTime) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1387 pWifiChannelStats->ccaBusyTime))
1388 {
1389 hddLog(VOS_TRACE_LEVEL_ERROR,
1390 FL("cfg80211_vendor_event_alloc failed") );
1391 kfree_skb(vendor_event);
1392 return ;
1393 }
1394 nla_nest_end(vendor_event, chInfo);
1395 }
1396 nla_nest_end(vendor_event, chList);
1397
1398 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1399 return;
1400}
1401
1402/*
1403 * hdd_link_layer_stats_ind_callback () - This function is called after
1404 * receiving Link Layer indications from FW.This callback converts the firmware
1405 * data to the NL data and send the same to the kernel/upper layers.
1406 */
1407static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1408 int indType,
1409 void *pRsp )
1410{
1411 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCtx;
1412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1413 int status;
1414
1415 status = wlan_hdd_validate_context(pHddCtx);
1416
1417 if (0 != status)
1418 {
1419 hddLog(VOS_TRACE_LEVEL_ERROR,
1420 FL("HDD context is not valid"));
1421 return;
1422 }
1423
1424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1425 "%s: Link Layer Indication indType: %d", __func__, indType);
1426 switch (indType)
1427 {
1428 case SIR_HAL_LL_STATS_RESULTS_RSP:
1429 {
1430 tpSirLLStatsResults linkLayerStatsResults =
1431 (tpSirLLStatsResults)pRsp;
1432
1433
1434 hddLog(VOS_TRACE_LEVEL_INFO,
1435 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1436 hddLog(VOS_TRACE_LEVEL_INFO,
1437 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1438 linkLayerStatsResults->paramId);
1439 hddLog(VOS_TRACE_LEVEL_INFO,
1440 "LL_STATS RESULTS RESPONSE ifaceId = %u",
1441 linkLayerStatsResults->ifaceId);
1442 hddLog(VOS_TRACE_LEVEL_INFO,
1443 "LL_STATS RESULTS RESPONSE respId = %u",
1444 linkLayerStatsResults->respId);
1445 hddLog(VOS_TRACE_LEVEL_INFO,
1446 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1447 linkLayerStatsResults->moreResultToFollow);
1448 hddLog(VOS_TRACE_LEVEL_INFO,
1449 "LL_STATS RESULTS RESPONSE result = %p",
1450 linkLayerStatsResults->result);
1451 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1452 {
1453 hdd_link_layer_process_radio_stats(pAdapter,
1454 (v_VOID_t *)linkLayerStatsResults->result);
1455 }
1456 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1457 {
1458 hdd_link_layer_process_iface_stats(pAdapter,
1459 (v_VOID_t *)linkLayerStatsResults->result);
1460 }
1461 else if ( linkLayerStatsResults->paramId &
1462 WMI_LINK_STATS_ALL_PEER )
1463 {
1464 hdd_link_layer_process_peer_stats(pAdapter,
1465 (v_VOID_t *)linkLayerStatsResults->result);
1466 } /* WMI_LINK_STATS_ALL_PEER */
1467 else
1468 {
1469 hddLog(VOS_TRACE_LEVEL_ERROR,
1470 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1471 }
1472
1473 break;
1474 }
1475 default:
1476 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1477 break;
1478 }
1479 return;
1480}
1481
1482const struct
1483nla_policy
1484qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1485{
1486 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1487 { .type = NLA_U32 },
1488 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1489 { .type = NLA_U32 },
1490};
1491
1492static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1493 struct wireless_dev *wdev,
1494 void *data,
1495 int data_len)
1496{
1497 int status;
1498 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301499 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301500 struct net_device *dev = wdev->netdev;
1501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1502 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1503
1504 status = wlan_hdd_validate_context(pHddCtx);
1505 if (0 != status)
1506 {
1507 hddLog(VOS_TRACE_LEVEL_ERROR,
1508 FL("HDD context is not valid"));
1509 return -EINVAL;
1510 }
1511
1512 if (NULL == pAdapter)
1513 {
1514 hddLog(VOS_TRACE_LEVEL_ERROR,
1515 FL("HDD adapter is Null"));
1516 return -ENODEV;
1517 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301518 /* check the LLStats Capability */
1519 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1520 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1521 {
1522 hddLog(VOS_TRACE_LEVEL_ERROR,
1523 FL("Link Layer Statistics not supported by Firmware"));
1524 return -EINVAL;
1525 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301526
1527 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1528 (struct nlattr *)data,
1529 data_len, qca_wlan_vendor_ll_set_policy))
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1532 return -EINVAL;
1533 }
1534 if (!tb_vendor
1535 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1538 return -EINVAL;
1539 }
1540 if (!tb_vendor[
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1542 {
1543 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1544 return -EINVAL;
1545 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301546 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301547 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301548
Dino Mycledf0a5d92014-07-04 09:41:55 +05301549 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301550 nla_get_u32(
1551 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1552
Dino Mycledf0a5d92014-07-04 09:41:55 +05301553 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301554 nla_get_u32(
1555 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1556
1557 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1558 * Hence the interface staId start from 1. Hence the staId matching the
1559 * interface in the firmware is sessionId + 1.
1560 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301561 linkLayerStatsSetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562
1563
1564 hddLog(VOS_TRACE_LEVEL_INFO,
1565 "LL_STATS_SET reqId = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301566 linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301568 "LL_STATS_SET staId = %d", linkLayerStatsSetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301571 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 hddLog(VOS_TRACE_LEVEL_INFO,
1573 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301574 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
1576 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1577 pHddCtx->hHal,
1578 pAdapter->sessionId,
1579 hdd_link_layer_stats_ind_callback,
1580 pAdapter))
1581 {
1582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1583 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584 return -EINVAL;
1585
1586 }
1587 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301588 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301589 {
1590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1591 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 return -EINVAL;
1593 }
1594
1595 pAdapter->isLinkLayerStatsSet = 1;
1596
1597 return 0;
1598}
1599
1600const struct
1601nla_policy
1602qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1603{
1604 /* Unsigned 32bit value provided by the caller issuing the GET stats
1605 * command. When reporting
1606 * the stats results, the driver uses the same value to indicate
1607 * which GET request the results
1608 * correspond to.
1609 */
1610 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1611
1612 /* Unsigned 32bit value . bit mask to identify what statistics are
1613 requested for retrieval */
1614 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1615};
1616
1617static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1618 struct wireless_dev *wdev,
1619 void *data,
1620 int data_len)
1621{
1622 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1623 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301624 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301625 struct net_device *dev = wdev->netdev;
1626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1627 int status;
1628
1629 status = wlan_hdd_validate_context(pHddCtx);
1630 if (0 != status)
1631 {
1632 hddLog(VOS_TRACE_LEVEL_ERROR,
1633 FL("HDD context is not valid"));
1634 return -EINVAL ;
1635 }
1636
1637 if (NULL == pAdapter)
1638 {
1639 hddLog(VOS_TRACE_LEVEL_FATAL,
1640 "%s: HDD adapter is Null", __func__);
1641 return -ENODEV;
1642 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301643 /* check the LLStats Capability */
1644 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1645 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1646 {
1647 hddLog(VOS_TRACE_LEVEL_ERROR,
1648 FL("Link Layer Statistics not supported by Firmware"));
1649 return -EINVAL;
1650 }
1651
Sunil Duttc69bccb2014-05-26 21:30:20 +05301652
1653 if (!pAdapter->isLinkLayerStatsSet)
1654 {
1655 hddLog(VOS_TRACE_LEVEL_FATAL,
1656 "%s: isLinkLayerStatsSet : %d",
1657 __func__, pAdapter->isLinkLayerStatsSet);
1658 return -EINVAL;
1659 }
1660
1661 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1662 (struct nlattr *)data,
1663 data_len, qca_wlan_vendor_ll_get_policy))
1664 {
1665 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1666 return -EINVAL;
1667 }
1668
1669 if (!tb_vendor
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1671 {
1672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1673 return -EINVAL;
1674 }
1675
1676 if (!tb_vendor
1677 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1680 return -EINVAL;
1681 }
1682
Sunil Duttc69bccb2014-05-26 21:30:20 +05301683
Dino Mycledf0a5d92014-07-04 09:41:55 +05301684 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 nla_get_u32( tb_vendor[
1686 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 nla_get_u32( tb_vendor[
1689 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1690
1691 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1692 * Hence the interface staId start from 1. Hence the staId matching the
1693 * interface in the firmware is sessionId + 1.
1694 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301695 linkLayerStatsGetReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696
1697 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301698 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301699 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 "LL_STATS_GET staId = %d", linkLayerStatsGetReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 hddLog(VOS_TRACE_LEVEL_INFO,
1702 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301704
1705 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301707 {
1708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1709 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301710 return -EINVAL;
1711 }
1712 return 0;
1713}
1714
1715const struct
1716nla_policy
1717qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1718{
1719 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1721 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1722 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1723};
1724
1725static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1726 struct wireless_dev *wdev,
1727 void *data,
1728 int data_len)
1729{
1730 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1731 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 struct net_device *dev = wdev->netdev;
1734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1735 u32 statsClearReqMask;
1736 u8 stopReq;
1737 int status;
1738
1739 status = wlan_hdd_validate_context(pHddCtx);
1740 if (0 != status)
1741 {
1742 hddLog(VOS_TRACE_LEVEL_ERROR,
1743 FL("HDD context is not valid"));
1744 return -EINVAL;
1745 }
1746
1747 if (NULL == pAdapter)
1748 {
1749 hddLog(VOS_TRACE_LEVEL_FATAL,
1750 "%s: HDD adapter is Null", __func__);
1751 return -ENODEV;
1752 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301753 /* check the LLStats Capability */
1754 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1755 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR,
1758 FL("Enable LLStats Capability"));
1759 return -EINVAL;
1760 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761
1762 if (!pAdapter->isLinkLayerStatsSet)
1763 {
1764 hddLog(VOS_TRACE_LEVEL_FATAL,
1765 "%s: isLinkLayerStatsSet : %d",
1766 __func__, pAdapter->isLinkLayerStatsSet);
1767 return -EINVAL;
1768 }
1769
1770 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1771 (struct nlattr *)data,
1772 data_len, qca_wlan_vendor_ll_clr_policy))
1773 {
1774 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1775 return -EINVAL;
1776 }
1777
1778 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1779
1780 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1781 {
1782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1783 return -EINVAL;
1784
1785 }
1786
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787
Dino Mycledf0a5d92014-07-04 09:41:55 +05301788 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789 nla_get_u32(
1790 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1791
Dino Mycledf0a5d92014-07-04 09:41:55 +05301792 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301793 nla_get_u8(
1794 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1795
1796 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301797 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798
1799 /* staId 0 in Firmware is reserved for Broadcast/Multicast data.
1800 * Hence the interface staId start from 1. Hence the staId matching the
1801 * interface in the firmware is sessionId + 1.
1802 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301803 linkLayerStatsClearReq.staId = pAdapter->sessionId + 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301804
1805 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301806 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301808 "LL_STATS_CLEAR staId = %d", linkLayerStatsClearReq.staId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301811 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301812 hddLog(VOS_TRACE_LEVEL_INFO,
1813 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301814 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815
1816 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301817 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301818 {
1819 struct sk_buff *temp_skbuff;
1820 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1821 2 * sizeof(u32) +
1822 NLMSG_HDRLEN);
1823
1824 if (temp_skbuff != NULL)
1825 {
1826
1827 if (nla_put_u32(temp_skbuff,
1828 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1829 statsClearReqMask) ||
1830 nla_put_u32(temp_skbuff,
1831 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1832 stopReq))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1835 kfree_skb(temp_skbuff);
1836 return -EINVAL;
1837 }
1838 /* If the ask is to stop the stats collection as part of clear
1839 * (stopReq = 1) , ensure that no further requests of get
1840 * go to the firmware by having isLinkLayerStatsSet set to 0.
1841 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301842 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 * case the firmware is just asked to clear the statistics.
1844 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301845 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 pAdapter->isLinkLayerStatsSet = 0;
1847 return cfg80211_vendor_cmd_reply(temp_skbuff);
1848 }
1849 return -ENOMEM;
1850 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301851 return -EINVAL;
1852}
1853#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1854
Dino Mycle6fb96c12014-06-10 11:52:40 +05301855#ifdef WLAN_FEATURE_EXTSCAN
1856static const struct nla_policy
1857wlan_hdd_extscan_config_policy
1858 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1859{
1860 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1861 { .type = NLA_U32 },
1862 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1863 { .type = NLA_U32 },
1864 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1866 { .type = NLA_U32 },
1867 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1868 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1869
1870 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1873 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1874 { .type = NLA_U8 },
1875 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1876 { .type = NLA_U32 },
1877 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1878 { .type = NLA_U32 },
1879 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1880 { .type = NLA_U32 },
1881 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1882 { .type = NLA_U8 },
1883 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1884 { .type = NLA_U8 },
1885 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1886 { .type = NLA_U8 },
1887
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1889 { .type = NLA_U32 },
1890 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1891 { .type = NLA_UNSPEC },
1892 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1893 { .type = NLA_S32 },
1894 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1895 { .type = NLA_S32 },
1896 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1897 { .type = NLA_U32 },
1898 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1899 { .type = NLA_U32 },
1900 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1901 { .type = NLA_U32 },
1902 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1903 = { .type = NLA_U32 },
1904 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1905 { .type = NLA_U32 },
1906 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1907 NLA_U32 },
1908};
1909
1910static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1911{
1912 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1913 struct sk_buff *skb = NULL;
1914 tpSirEXTScanCapabilitiesEvent pData =
1915 (tpSirEXTScanCapabilitiesEvent) pMsg;
1916
1917 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1919 "or pData(%p) is null"), pData);
1920 return;
1921 }
1922
1923 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1924 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1925 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1926 GFP_KERNEL);
1927
1928 if (!skb) {
1929 hddLog(VOS_TRACE_LEVEL_ERROR,
1930 FL("cfg80211_vendor_event_alloc failed"));
1931 return;
1932 }
1933
1934 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1935 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1936 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1937 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1938 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1939 pData->maxRssiSampleSize);
1940 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1941 pData->maxScanReportingThreshold);
1942 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1944 pData->maxSignificantWifiChangeAPs);
1945 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1946 pData->maxBsidHistoryEntries);
1947
1948 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1949 pData->requestId) ||
1950 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1951 nla_put_u32(skb,
1952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1953 pData->scanCacheSize) ||
1954 nla_put_u32(skb,
1955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1956 pData->scanBuckets) ||
1957 nla_put_u32(skb,
1958 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1959 pData->maxApPerScan) ||
1960 nla_put_u32(skb,
1961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1962 pData->maxRssiSampleSize) ||
1963 nla_put_u32(skb,
1964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1965 pData->maxScanReportingThreshold) ||
1966 nla_put_u32(skb,
1967 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1968 pData->maxHotlistAPs) ||
1969 nla_put_u32(skb,
1970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1971 pData->maxSignificantWifiChangeAPs) ||
1972 nla_put_u32(skb,
1973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1974 pData->maxBsidHistoryEntries)) {
1975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1976 goto nla_put_failure;
1977 }
1978
1979 cfg80211_vendor_event(skb, GFP_KERNEL);
1980 return;
1981
1982nla_put_failure:
1983 kfree_skb(skb);
1984 return;
1985}
1986
1987
1988static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1989{
1990 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1991 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1992 struct sk_buff *skb = NULL;
1993 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
1994
1995
1996 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1998 "or pData(%p) is null"), pData);
1999 return;
2000 }
2001
2002 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2003 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2004 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2005 GFP_KERNEL);
2006
2007 if (!skb) {
2008 hddLog(VOS_TRACE_LEVEL_ERROR,
2009 FL("cfg80211_vendor_event_alloc failed"));
2010 return;
2011 }
2012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2013 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2014 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2015
2016 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2017 pData->requestId) ||
2018 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2020 goto nla_put_failure;
2021 }
2022
2023 /*
2024 * Store the Request ID for comparing with the requestID obtained
2025 * in other requests.HDD shall return a failure is the extscan_stop
2026 * request is issued with a different requestId as that of the
2027 * extscan_start request. Also, This requestId shall be used while
2028 * indicating the full scan results to the upper layers.
2029 * The requestId is stored with the assumption that the firmware
2030 * shall return the ext scan start request's requestId in ext scan
2031 * start response.
2032 */
2033 if (pData->status == 0)
2034 pMac->sme.extScanStartReqId = pData->requestId;
2035
2036
2037 cfg80211_vendor_event(skb, GFP_KERNEL);
2038 return;
2039
2040nla_put_failure:
2041 kfree_skb(skb);
2042 return;
2043}
2044
2045
2046static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2047{
2048 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2049 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2050 struct sk_buff *skb = NULL;
2051
2052 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2054 "or pData(%p) is null"), pData);
2055 return;
2056 }
2057
2058 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2059 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2060 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2061 GFP_KERNEL);
2062
2063 if (!skb) {
2064 hddLog(VOS_TRACE_LEVEL_ERROR,
2065 FL("cfg80211_vendor_event_alloc failed"));
2066 return;
2067 }
2068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2069 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2070
2071 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2072 pData->requestId) ||
2073 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2075 goto nla_put_failure;
2076 }
2077
2078 cfg80211_vendor_event(skb, GFP_KERNEL);
2079 return;
2080
2081nla_put_failure:
2082 kfree_skb(skb);
2083 return;
2084}
2085
2086
2087static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2088 void *pMsg)
2089{
2090 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2091 struct sk_buff *skb = NULL;
2092 tpSirEXTScanSetBssidHotListRspParams pData =
2093 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2094
2095 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2097 "or pData(%p) is null"), pData);
2098 return;
2099 }
2100 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2101 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2102 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2103 GFP_KERNEL);
2104
2105 if (!skb) {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("cfg80211_vendor_event_alloc failed"));
2108 return;
2109 }
2110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2111 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2112 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2113
2114 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2115 pData->requestId) ||
2116 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2118 goto nla_put_failure;
2119 }
2120
2121 cfg80211_vendor_event(skb, GFP_KERNEL);
2122 return;
2123
2124nla_put_failure:
2125 kfree_skb(skb);
2126 return;
2127}
2128
2129static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2130 void *pMsg)
2131{
2132 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2133 struct sk_buff *skb = NULL;
2134 tpSirEXTScanResetBssidHotlistRspParams pData =
2135 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2136
2137 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2139 "or pData(%p) is null"), pData);
2140 return;
2141 }
2142
2143 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2144 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2145 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2146 GFP_KERNEL);
2147
2148 if (!skb) {
2149 hddLog(VOS_TRACE_LEVEL_ERROR,
2150 FL("cfg80211_vendor_event_alloc failed"));
2151 return;
2152 }
2153 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2154 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2155
2156 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2157 pData->requestId) ||
2158 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2160 goto nla_put_failure;
2161 }
2162
2163 cfg80211_vendor_event(skb, GFP_KERNEL);
2164 return;
2165
2166nla_put_failure:
2167 kfree_skb(skb);
2168 return;
2169}
2170
2171
2172static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2173 void *pMsg)
2174{
2175 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2176 struct sk_buff *skb = NULL;
2177 tpSirEXTScanSetSignificantChangeRspParams pData =
2178 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2179
2180 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2182 "or pData(%p) is null"), pData);
2183 return;
2184 }
2185
2186 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2187 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2188 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2189 GFP_KERNEL);
2190
2191 if (!skb) {
2192 hddLog(VOS_TRACE_LEVEL_ERROR,
2193 FL("cfg80211_vendor_event_alloc failed"));
2194 return;
2195 }
2196 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2197 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2198 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2199
2200 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2201 pData->requestId) ||
2202 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2204 goto nla_put_failure;
2205 }
2206
2207 cfg80211_vendor_event(skb, GFP_KERNEL);
2208 return;
2209
2210nla_put_failure:
2211 kfree_skb(skb);
2212 return;
2213}
2214
2215
2216static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2217 void *pMsg)
2218{
2219 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2220 struct sk_buff *skb = NULL;
2221 tpSirEXTScanResetSignificantChangeRspParams pData =
2222 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2223
2224 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2226 "or pData(%p) is null"), pData);
2227 return;
2228 }
2229
2230 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2231 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2232 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2233 GFP_KERNEL);
2234
2235 if (!skb) {
2236 hddLog(VOS_TRACE_LEVEL_ERROR,
2237 FL("cfg80211_vendor_event_alloc failed"));
2238 return;
2239 }
2240 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2241 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2242 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2243
2244 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2245 pData->requestId) ||
2246 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2248 goto nla_put_failure;
2249 }
2250
2251 cfg80211_vendor_event(skb, GFP_KERNEL);
2252 return;
2253
2254nla_put_failure:
2255 kfree_skb(skb);
2256 return;
2257}
2258
2259static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2260 void *pMsg)
2261{
2262 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2263 struct sk_buff *skb = NULL;
2264 tANI_U32 i = 0, j, resultsPerEvent;
2265 tANI_S32 totalResults;
2266 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2267 tpSirWifiScanResult pSirWifiScanResult;
2268
2269 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2271 "or pData(%p) is null"), pData);
2272 return;
2273 }
2274 totalResults = pData->numOfAps;
2275 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2276 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2277 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2278
2279 do{
2280 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2281 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2282 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2283
2284 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2285 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2286 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2287 GFP_KERNEL);
2288
2289 if (!skb) {
2290 hddLog(VOS_TRACE_LEVEL_ERROR,
2291 FL("cfg80211_vendor_event_alloc failed"));
2292 return;
2293 }
2294
2295 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2296
2297 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2298 pData->requestId) ||
2299 nla_put_u32(skb,
2300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2301 resultsPerEvent)) {
2302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2303 goto fail;
2304 }
2305 if (nla_put_u8(skb,
2306 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2307 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2308 {
2309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2310 goto fail;
2311 }
2312
2313 if (resultsPerEvent) {
2314 struct nlattr *aps;
2315
2316 aps = nla_nest_start(skb,
2317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2318 if (!aps)
2319 {
2320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2321 goto fail;
2322 }
2323
2324 for (j = 0; j < resultsPerEvent; j++, i++) {
2325 struct nlattr *ap;
2326 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2327 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2328
2329 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2330 "Ssid (%s)"
2331 "Bssid: %pM "
2332 "Channel (%u)"
2333 "Rssi (%d)"
2334 "RTT (%u)"
2335 "RTT_SD (%u)",
2336 i,
2337 pSirWifiScanResult->ts,
2338 pSirWifiScanResult->ssid,
2339 pSirWifiScanResult->bssid,
2340 pSirWifiScanResult->channel,
2341 pSirWifiScanResult->rssi,
2342 pSirWifiScanResult->rtt,
2343 pSirWifiScanResult->rtt_sd);
2344
2345 ap = nla_nest_start(skb, j + 1);
2346 if (!ap)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2349 goto fail;
2350 }
2351
2352 if (nla_put_u64(skb,
2353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2354 pSirWifiScanResult->ts) )
2355 {
2356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2357 goto fail;
2358 }
2359 if (nla_put(skb,
2360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2361 sizeof(pSirWifiScanResult->ssid),
2362 pSirWifiScanResult->ssid) )
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2365 goto fail;
2366 }
2367 if (nla_put(skb,
2368 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2369 sizeof(pSirWifiScanResult->bssid),
2370 pSirWifiScanResult->bssid) )
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2373 goto fail;
2374 }
2375 if (nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2377 pSirWifiScanResult->channel) )
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2380 goto fail;
2381 }
2382 if (nla_put_u32(skb,
2383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2384 pSirWifiScanResult->rssi) )
2385 {
2386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2387 goto fail;
2388 }
2389 if (nla_put_u32(skb,
2390 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2391 pSirWifiScanResult->rtt) )
2392 {
2393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2394 goto fail;
2395 }
2396 if (nla_put_u32(skb,
2397 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2398 pSirWifiScanResult->rtt_sd))
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2401 goto fail;
2402 }
2403
2404 nla_nest_end(skb, ap);
2405 }
2406 nla_nest_end(skb, aps);
2407
2408 }
2409 cfg80211_vendor_event(skb, GFP_KERNEL);
2410 } while (totalResults > 0);
2411
2412 return;
2413fail:
2414 kfree_skb(skb);
2415 return;
2416}
2417
2418static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2419 void *pMsg)
2420{
2421 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2422 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2423 struct sk_buff *skb = NULL;
2424 tANI_U32 i;
2425
2426 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2428 "or pData(%p) is null"), pData);
2429 return;
2430 }
2431
2432 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2433 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2434 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2435 GFP_KERNEL);
2436
2437 if (!skb) {
2438 hddLog(VOS_TRACE_LEVEL_ERROR,
2439 FL("cfg80211_vendor_event_alloc failed"));
2440 return;
2441 }
2442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2443 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2444 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2445 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2446
2447 for (i = 0; i < pData->numOfAps; i++) {
2448 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2449 "Ssid (%s) "
2450 "Bssid (" MAC_ADDRESS_STR ") "
2451 "Channel (%u) "
2452 "Rssi (%d) "
2453 "RTT (%u) "
2454 "RTT_SD (%u) ",
2455 i,
2456 pData->ap[i].ts,
2457 pData->ap[i].ssid,
2458 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2459 pData->ap[i].channel,
2460 pData->ap[i].rssi,
2461 pData->ap[i].rtt,
2462 pData->ap[i].rtt_sd);
2463 }
2464
2465 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2466 pData->requestId) ||
2467 nla_put_u32(skb,
2468 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2469 pData->numOfAps)) {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2471 goto fail;
2472 }
2473 if (pData->numOfAps) {
2474 struct nlattr *aps;
2475
2476 aps = nla_nest_start(skb,
2477 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2478 if (!aps)
2479 goto fail;
2480
2481 for (i = 0; i < pData->numOfAps; i++) {
2482 struct nlattr *ap;
2483
2484 ap = nla_nest_start(skb, i + 1);
2485 if (!ap)
2486 goto fail;
2487
2488 if (nla_put_u64(skb,
2489 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2490 pData->ap[i].ts) ||
2491 nla_put(skb,
2492 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2493 sizeof(pData->ap[i].ssid),
2494 pData->ap[i].ssid) ||
2495 nla_put(skb,
2496 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2497 sizeof(pData->ap[i].bssid),
2498 pData->ap[i].bssid) ||
2499 nla_put_u32(skb,
2500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2501 pData->ap[i].channel) ||
2502 nla_put_s32(skb,
2503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2504 pData->ap[i].rssi) ||
2505 nla_put_u32(skb,
2506 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2507 pData->ap[i].rtt) ||
2508 nla_put_u32(skb,
2509 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2510 pData->ap[i].rtt_sd))
2511 goto fail;
2512
2513 nla_nest_end(skb, ap);
2514 }
2515 nla_nest_end(skb, aps);
2516
2517 if (nla_put_u8(skb,
2518 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2519 pData->moreData))
2520 goto fail;
2521 }
2522
2523 cfg80211_vendor_event(skb, GFP_KERNEL);
2524 return;
2525
2526fail:
2527 kfree_skb(skb);
2528 return;
2529
2530}
2531static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2532 void *pMsg)
2533{
2534 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2535 struct sk_buff *skb = NULL;
2536 tANI_U32 i, j;
2537 tpSirWifiSignificantChangeEvent pData =
2538 (tpSirWifiSignificantChangeEvent) pMsg;
2539
2540 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2542 "or pData(%p) is null"), pData);
2543 return;
2544 }
2545 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2546 EXTSCAN_EVENT_BUF_SIZE,
2547 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2548 GFP_KERNEL);
2549
2550 if (!skb) {
2551 hddLog(VOS_TRACE_LEVEL_ERROR,
2552 FL("cfg80211_vendor_event_alloc failed"));
2553 return;
2554 }
2555 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2556 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2557 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2558 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2559 pData->numSigRssiBss);
2560 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2561
2562 for (i = 0; i < pData->numSigRssiBss; i++) {
2563 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2564 " num RSSI %u ",
2565 i, pData->sigRssiResult[i].bssid,
2566 pData->sigRssiResult[i].channel,
2567 pData->sigRssiResult[i].numRssi);
2568
2569 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2570
2571 hddLog(VOS_TRACE_LEVEL_INFO,
2572 " [%d]",
2573 pData->sigRssiResult[i].rssi[0]);
2574
2575 }
2576 }
2577
2578
2579 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2580 pData->requestId) ||
2581 nla_put_u32(skb,
2582 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2583 pData->numSigRssiBss)) {
2584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2585 goto fail;
2586 }
2587
2588 if (pData->numSigRssiBss) {
2589 struct nlattr *aps;
2590 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2591 if (!aps)
2592 goto fail;
2593 for (i = 0; i < pData->numSigRssiBss; i++) {
2594 struct nlattr *ap;
2595
2596 ap = nla_nest_start(skb, i);
2597 if (!ap)
2598 goto fail;
2599 if (nla_put(skb,
2600 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2601 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2602 nla_put_u32(skb,
2603 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2604 pData->sigRssiResult[i].channel) ||
2605 nla_put_u32(skb,
2606 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2607 pData->sigRssiResult[i].numRssi) ||
2608 nla_put(skb,
2609 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2610 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2611 pData->sigRssiResult[i].rssi))
2612 goto fail;
2613 nla_nest_end(skb, ap);
2614 }
2615 nla_nest_end(skb, aps);
2616 if (nla_put_u8(skb,
2617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2618 pData->moreData))
2619 goto fail;
2620 }
2621 cfg80211_vendor_event(skb, GFP_KERNEL);
2622 return;
2623fail:
2624 kfree_skb(skb);
2625 return;
2626}
2627
2628static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2629 void *pMsg)
2630{
2631 struct sk_buff *skb;
2632 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2633 tpSirWifiFullScanResultEvent pData =
2634 (tpSirWifiFullScanResultEvent) (pMsg);
2635
2636 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2638 "or pData(%p) is null"), pData);
2639 return;
2640 }
2641
2642 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2643 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2644 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2645 GFP_KERNEL);
2646
2647 if (!skb) {
2648 hddLog(VOS_TRACE_LEVEL_ERROR,
2649 FL("cfg80211_vendor_event_alloc failed"));
2650 return;
2651 }
2652
2653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2655 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2657 "Ssid (%s)"
2658 "Bssid (" MAC_ADDRESS_STR ")"
2659 "Channel (%u)"
2660 "Rssi (%d)"
2661 "RTT (%u)"
2662 "RTT_SD (%u)"),
2663 pData->ap.ts,
2664 pData->ap.ssid,
2665 MAC_ADDR_ARRAY(pData->ap.bssid),
2666 pData->ap.channel,
2667 pData->ap.rssi,
2668 pData->ap.rtt,
2669 pData->ap.rtt_sd);
2670 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2672 pData->requestId) ||
2673 nla_put_u64(skb,
2674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2675 pData->ap.ts) ||
2676 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2677 sizeof(pData->ap.ssid),
2678 pData->ap.ssid) ||
2679 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2680 WNI_CFG_BSSID_LEN,
2681 pData->ap.bssid) ||
2682 nla_put_u32(skb,
2683 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2684 pData->ap.channel) ||
2685 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2686 pData->ap.rssi) ||
2687 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2688 pData->ap.rtt) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2691 pData->ap.rtt_sd) ||
2692 nla_put_u16(skb,
2693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2694 pData->ap.beaconPeriod) ||
2695 nla_put_u16(skb,
2696 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2697 pData->ap.capability) ||
2698 nla_put_u32(skb,
2699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2700 pData->ieLength))
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2703 goto nla_put_failure;
2704 }
2705 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2706 pData->ieLength,
2707 pData->ie))
2708 {
2709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2710 goto nla_put_failure;
2711 }
2712
2713 cfg80211_vendor_event(skb, GFP_KERNEL);
2714 return;
2715
2716nla_put_failure:
2717 kfree_skb(skb);
2718 return;
2719}
2720
2721static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2722 void *pMsg)
2723{
2724 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2725 struct sk_buff *skb = NULL;
2726 tpSirEXTScanResultsAvailableIndParams pData =
2727 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2728
2729 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2731 "or pData(%p) is null"), pData);
2732 return;
2733 }
2734
2735 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2736 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2737 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2738 GFP_KERNEL);
2739
2740 if (!skb) {
2741 hddLog(VOS_TRACE_LEVEL_ERROR,
2742 FL("cfg80211_vendor_event_alloc failed"));
2743 return;
2744 }
2745
2746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2747 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2748 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2749 pData->numResultsAvailable);
2750 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2751 pData->requestId) ||
2752 nla_put_u32(skb,
2753 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2754 pData->numResultsAvailable)) {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2756 goto nla_put_failure;
2757 }
2758
2759 cfg80211_vendor_event(skb, GFP_KERNEL);
2760 return;
2761
2762nla_put_failure:
2763 kfree_skb(skb);
2764 return;
2765}
2766
2767static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2768{
2769 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2770 struct sk_buff *skb = NULL;
2771 tpSirEXTScanProgressIndParams pData =
2772 (tpSirEXTScanProgressIndParams) pMsg;
2773
2774 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2776 "or pData(%p) is null"), pData);
2777 return;
2778 }
2779
2780 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2781 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2782 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2783 GFP_KERNEL);
2784
2785 if (!skb) {
2786 hddLog(VOS_TRACE_LEVEL_ERROR,
2787 FL("cfg80211_vendor_event_alloc failed"));
2788 return;
2789 }
2790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2791 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2792 pData->extScanEventType);
2793 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2794 pData->status);
2795
2796 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2797 pData->extScanEventType) ||
2798 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2800 pData->requestId) ||
2801 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2803 pData->status)) {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2805 goto nla_put_failure;
2806 }
2807
2808 cfg80211_vendor_event(skb, GFP_KERNEL);
2809 return;
2810
2811nla_put_failure:
2812 kfree_skb(skb);
2813 return;
2814}
2815
2816void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2817 void *pMsg)
2818{
2819 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2820
2821 if (wlan_hdd_validate_context(pHddCtx)) {
2822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2823 return;
2824 }
2825
2826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2827
2828
2829 switch(evType) {
2830 case SIR_HAL_EXTSCAN_START_RSP:
2831 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2832 break;
2833
2834 case SIR_HAL_EXTSCAN_STOP_RSP:
2835 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2836 break;
2837 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2838 /* There is no need to send this response to upper layer
2839 Just log the message */
2840 hddLog(VOS_TRACE_LEVEL_INFO,
2841 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2842 break;
2843 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2844 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2845 break;
2846
2847 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2848 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2849 break;
2850
2851 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2852 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2853 break;
2854
2855 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2856 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2857 break;
2858 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2859 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2860 break;
2861 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2862 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2863 break;
2864 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2865 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2866 break;
2867 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2868 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2869 break;
2870 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2871 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2872 break;
2873 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2874 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2875 break;
2876 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2877 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2878 break;
2879 default:
2880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2881 break;
2882 }
2883}
2884
2885static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2886 struct wireless_dev *wdev,
2887 void *data, int dataLen)
2888{
Dino Myclee8843b32014-07-04 14:21:45 +05302889 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890 struct net_device *dev = wdev->netdev;
2891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2893 struct nlattr
2894 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2895 eHalStatus status;
2896
2897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2898 status = wlan_hdd_validate_context(pHddCtx);
2899 if (0 != status)
2900 {
2901 hddLog(VOS_TRACE_LEVEL_ERROR,
2902 FL("HDD context is not valid"));
2903 return -EINVAL;
2904 }
Dino Myclee8843b32014-07-04 14:21:45 +05302905 /* check the EXTScan Capability */
2906 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2907 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2908 {
2909 hddLog(VOS_TRACE_LEVEL_ERROR,
2910 FL("EXTScan not enabled/supported by Firmware"));
2911 return -EINVAL;
2912 }
2913
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2915 data, dataLen,
2916 wlan_hdd_extscan_config_policy)) {
2917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2918 return -EINVAL;
2919 }
2920
2921 /* Parse and fetch request Id */
2922 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2924 return -EINVAL;
2925 }
2926
Dino Mycle6fb96c12014-06-10 11:52:40 +05302927
Dino Myclee8843b32014-07-04 14:21:45 +05302928 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931
Dino Myclee8843b32014-07-04 14:21:45 +05302932 reqMsg.sessionId = pAdapter->sessionId;
2933 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Dino Myclee8843b32014-07-04 14:21:45 +05302935 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302936 if (!HAL_STATUS_SUCCESS(status)) {
2937 hddLog(VOS_TRACE_LEVEL_ERROR,
2938 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 return -EINVAL;
2940 }
2941
2942 return 0;
2943}
2944
2945
2946static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2947 struct wireless_dev *wdev,
2948 void *data, int dataLen)
2949{
Dino Myclee8843b32014-07-04 14:21:45 +05302950 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302951 struct net_device *dev = wdev->netdev;
2952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2953 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2954 struct nlattr
2955 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2956 eHalStatus status;
2957
2958 status = wlan_hdd_validate_context(pHddCtx);
2959 if (0 != status)
2960 {
2961 hddLog(VOS_TRACE_LEVEL_ERROR,
2962 FL("HDD context is not valid"));
2963 return -EINVAL;
2964 }
Dino Myclee8843b32014-07-04 14:21:45 +05302965 /* check the EXTScan Capability */
2966 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2967 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2968 {
2969 hddLog(VOS_TRACE_LEVEL_ERROR,
2970 FL("EXTScan not enabled/supported by Firmware"));
2971 return -EINVAL;
2972 }
2973
Dino Mycle6fb96c12014-06-10 11:52:40 +05302974 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2975 data, dataLen,
2976 wlan_hdd_extscan_config_policy)) {
2977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2978 return -EINVAL;
2979 }
2980 /* Parse and fetch request Id */
2981 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2983 return -EINVAL;
2984 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302985
Dino Myclee8843b32014-07-04 14:21:45 +05302986 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302987 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2988
Dino Myclee8843b32014-07-04 14:21:45 +05302989 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302990
Dino Myclee8843b32014-07-04 14:21:45 +05302991 reqMsg.sessionId = pAdapter->sessionId;
2992 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302993
2994 /* Parse and fetch flush parameter */
2995 if (!tb
2996 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
2997 {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
2999 goto failed;
3000 }
Dino Myclee8843b32014-07-04 14:21:45 +05303001 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303002 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3003
Dino Myclee8843b32014-07-04 14:21:45 +05303004 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303005
Dino Myclee8843b32014-07-04 14:21:45 +05303006 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303007 if (!HAL_STATUS_SUCCESS(status)) {
3008 hddLog(VOS_TRACE_LEVEL_ERROR,
3009 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 return -EINVAL;
3011 }
3012 return 0;
3013
3014failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303015 return -EINVAL;
3016}
3017
3018static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3019 struct wireless_dev *wdev,
3020 void *data, int dataLen)
3021{
3022 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3023 struct net_device *dev = wdev->netdev;
3024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3025 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3026 struct nlattr
3027 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3028 struct nlattr
3029 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3030 struct nlattr *apTh;
3031 eHalStatus status;
3032 tANI_U8 i = 0;
3033 int rem;
3034
3035 status = wlan_hdd_validate_context(pHddCtx);
3036 if (0 != status)
3037 {
3038 hddLog(VOS_TRACE_LEVEL_ERROR,
3039 FL("HDD context is not valid"));
3040 return -EINVAL;
3041 }
Dino Myclee8843b32014-07-04 14:21:45 +05303042 /* check the EXTScan Capability */
3043 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3044 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3045 {
3046 hddLog(VOS_TRACE_LEVEL_ERROR,
3047 FL("EXTScan not enabled/supported by Firmware"));
3048 return -EINVAL;
3049 }
3050
Dino Mycle6fb96c12014-06-10 11:52:40 +05303051 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3052 data, dataLen,
3053 wlan_hdd_extscan_config_policy)) {
3054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3055 return -EINVAL;
3056 }
3057
3058 /* Parse and fetch request Id */
3059 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3061 return -EINVAL;
3062 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303063 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3064 vos_mem_malloc(sizeof(*pReqMsg));
3065 if (!pReqMsg) {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3067 return -ENOMEM;
3068 }
3069
Dino Myclee8843b32014-07-04 14:21:45 +05303070
Dino Mycle6fb96c12014-06-10 11:52:40 +05303071 pReqMsg->requestId = nla_get_u32(
3072 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3074
3075 /* Parse and fetch number of APs */
3076 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3078 goto fail;
3079 }
3080
3081 pReqMsg->sessionId = pAdapter->sessionId;
3082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3083
3084 pReqMsg->numAp = nla_get_u32(
3085 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3087
3088 nla_for_each_nested(apTh,
3089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3090 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3091 nla_data(apTh), nla_len(apTh),
3092 NULL)) {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3094 goto fail;
3095 }
3096
3097 /* Parse and fetch MAC address */
3098 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3100 goto fail;
3101 }
3102 memcpy(pReqMsg->ap[i].bssid, nla_data(
3103 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3104 sizeof(tSirMacAddr));
3105 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3106
3107 /* Parse and fetch low RSSI */
3108 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3110 goto fail;
3111 }
3112 pReqMsg->ap[i].low = nla_get_s32(
3113 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3114 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3115
3116 /* Parse and fetch high RSSI */
3117 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3119 goto fail;
3120 }
3121 pReqMsg->ap[i].high = nla_get_s32(
3122 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3123 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3124 pReqMsg->ap[i].high);
3125
3126 /* Parse and fetch channel */
3127 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3129 goto fail;
3130 }
3131 pReqMsg->ap[i].channel = nla_get_u32(
3132 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3133 hddLog(VOS_TRACE_LEVEL_INFO,
3134 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3135 i++;
3136 }
3137 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3138 if (!HAL_STATUS_SUCCESS(status)) {
3139 hddLog(VOS_TRACE_LEVEL_ERROR,
3140 FL("sme_SetBssHotlist failed(err=%d)"), status);
3141 vos_mem_free(pReqMsg);
3142 return -EINVAL;
3143 }
3144
Dino Myclee8843b32014-07-04 14:21:45 +05303145 vos_mem_free(pReqMsg);
3146
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return 0;
3148
3149fail:
3150 vos_mem_free(pReqMsg);
3151 return -EINVAL;
3152}
3153
3154static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3155 struct wireless_dev *wdev,
3156 void *data, int dataLen)
3157{
3158 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3159 struct net_device *dev = wdev->netdev;
3160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3161 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3162 struct nlattr
3163 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3164 struct nlattr
3165 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3166 struct nlattr *apTh;
3167 eHalStatus status;
3168 int i = 0;
3169 int rem;
3170
3171 status = wlan_hdd_validate_context(pHddCtx);
3172 if (0 != status)
3173 {
3174 hddLog(VOS_TRACE_LEVEL_ERROR,
3175 FL("HDD context is not valid"));
3176 return -EINVAL;
3177 }
Dino Myclee8843b32014-07-04 14:21:45 +05303178 /* check the EXTScan Capability */
3179 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3180 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3181 {
3182 hddLog(VOS_TRACE_LEVEL_ERROR,
3183 FL("EXTScan not enabled/supported by Firmware"));
3184 return -EINVAL;
3185 }
3186
Dino Mycle6fb96c12014-06-10 11:52:40 +05303187 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3188 data, dataLen,
3189 wlan_hdd_extscan_config_policy)) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3191 return -EINVAL;
3192 }
3193
3194 /* Parse and fetch request Id */
3195 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3197 return -EINVAL;
3198 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303199 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303200 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3203 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204 }
3205
Dino Myclee8843b32014-07-04 14:21:45 +05303206
3207
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 pReqMsg->requestId = nla_get_u32(
3209 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3211
3212 /* Parse and fetch RSSI sample size */
3213 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3214 {
3215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3216 goto fail;
3217 }
3218 pReqMsg->rssiSampleSize = nla_get_u32(
3219 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3220 hddLog(VOS_TRACE_LEVEL_INFO,
3221 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3222
3223 /* Parse and fetch lost AP sample size */
3224 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3225 {
3226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3227 goto fail;
3228 }
3229 pReqMsg->lostApSampleSize = nla_get_u32(
3230 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3231 hddLog(VOS_TRACE_LEVEL_INFO,
3232 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3233 /* Parse and fetch minimum Breaching */
3234 if (!tb
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3237 goto fail;
3238 }
3239 pReqMsg->minBreaching = nla_get_u32(
3240 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3241 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3242
3243 /* Parse and fetch number of APs */
3244 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3246 goto fail;
3247 }
3248 pReqMsg->numAp = nla_get_u32(
3249 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3251
3252 pReqMsg->sessionId = pAdapter->sessionId;
3253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3254
3255 nla_for_each_nested(apTh,
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3257 if(nla_parse(tb2,
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3259 nla_data(apTh), nla_len(apTh),
3260 NULL)) {
3261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3262 goto fail;
3263 }
3264
3265 /* Parse and fetch MAC address */
3266 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3268 goto fail;
3269 }
3270 memcpy(pReqMsg->ap[i].bssid, nla_data(
3271 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3272 sizeof(tSirMacAddr));
3273
3274 /* Parse and fetch low RSSI */
3275 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3277 goto fail;
3278 }
3279 pReqMsg->ap[i].low = nla_get_s32(
3280 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3281 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3282
3283 /* Parse and fetch high RSSI */
3284 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3286 goto fail;
3287 }
3288 pReqMsg->ap[i].high = nla_get_s32(
3289 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3290 hddLog(VOS_TRACE_LEVEL_INFO,
3291 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3292
3293 /* Parse and fetch channel */
3294 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3296 goto fail;
3297 }
3298 pReqMsg->ap[i].channel = nla_get_u32(
3299 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3300 hddLog(VOS_TRACE_LEVEL_INFO,
3301 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3302 i++;
3303 }
3304
3305 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3306 if (!HAL_STATUS_SUCCESS(status)) {
3307 hddLog(VOS_TRACE_LEVEL_ERROR,
3308 FL("sme_SetSignificantChange failed(err=%d)"), status);
3309 vos_mem_free(pReqMsg);
3310 return -EINVAL;
3311 }
Dino Myclee8843b32014-07-04 14:21:45 +05303312 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303313 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3314 return 0;
3315
3316fail:
3317 vos_mem_free(pReqMsg);
3318 return -EINVAL;
3319}
3320
3321static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3322 struct wireless_dev *wdev,
3323 void *data, int dataLen)
3324{
3325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3326 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3327 tANI_U8 numChannels = 0;
3328 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3329 tANI_U32 requestId;
3330 tWifiBand wifiBand;
3331 eHalStatus status;
3332 struct sk_buff *replySkb;
3333 tANI_U8 i;
3334
3335 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3336 status = wlan_hdd_validate_context(pHddCtx);
3337 if (0 != status)
3338 {
3339 hddLog(VOS_TRACE_LEVEL_ERROR,
3340 FL("HDD context is not valid"));
3341 return -EINVAL;
3342 }
Dino Myclee8843b32014-07-04 14:21:45 +05303343 /* check the EXTScan Capability */
3344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3346 {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("EXTScan not enabled/supported by Firmware"));
3349 return -EINVAL;
3350 }
3351
Dino Mycle6fb96c12014-06-10 11:52:40 +05303352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3353 data, dataLen,
3354 wlan_hdd_extscan_config_policy)) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3356 return -EINVAL;
3357 }
3358
3359 /* Parse and fetch request Id */
3360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3362 return -EINVAL;
3363 }
3364 requestId = nla_get_u32(
3365 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3367
3368 /* Parse and fetch wifi band */
3369 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3370 {
3371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3372 return -EINVAL;
3373 }
3374 wifiBand = nla_get_u32(
3375 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3376 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3377
3378 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3379 wifiBand, ChannelList,
3380 &numChannels);
3381 if (eHAL_STATUS_SUCCESS != status) {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3384 return -EINVAL;
3385 }
3386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3387 for (i = 0; i < numChannels; i++)
3388 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3389
3390 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3391 sizeof(u32) * numChannels +
3392 NLMSG_HDRLEN);
3393
3394 if (!replySkb) {
3395 hddLog(VOS_TRACE_LEVEL_ERROR,
3396 FL("valid channels: buffer alloc fail"));
3397 return -EINVAL;
3398 }
3399 if (nla_put_u32(replySkb,
3400 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3401 numChannels) ||
3402 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3403 sizeof(u32) * numChannels, ChannelList)) {
3404
3405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3406 kfree_skb(replySkb);
3407 return -EINVAL;
3408 }
3409
3410 return cfg80211_vendor_cmd_reply(replySkb);
3411}
3412
3413static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3414 struct wireless_dev *wdev,
3415 void *data, int dataLen)
3416{
Dino Myclee8843b32014-07-04 14:21:45 +05303417 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 struct net_device *dev = wdev->netdev;
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3421 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3422 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3423 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3424 struct nlattr *buckets;
3425 struct nlattr *channels;
3426 int rem1;
3427 int rem2;
3428 eHalStatus status;
3429 tANI_U8 bktIndex;
3430 tANI_U32 i = 0, j = 0;
3431
3432 status = wlan_hdd_validate_context(pHddCtx);
3433 if (0 != status)
3434 {
3435 hddLog(VOS_TRACE_LEVEL_ERROR,
3436 FL("HDD context is not valid"));
3437 return -EINVAL;
3438 }
Dino Myclee8843b32014-07-04 14:21:45 +05303439 /* check the EXTScan Capability */
3440 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3441 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3442 {
3443 hddLog(VOS_TRACE_LEVEL_ERROR,
3444 FL("EXTScan not enabled/supported by Firmware"));
3445 return -EINVAL;
3446 }
3447
Dino Mycle6fb96c12014-06-10 11:52:40 +05303448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3449 data, dataLen,
3450 wlan_hdd_extscan_config_policy)) {
3451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3452 return -EINVAL;
3453 }
3454
3455 /* Parse and fetch request Id */
3456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3458 return -EINVAL;
3459 }
3460
Dino Myclee8843b32014-07-04 14:21:45 +05303461 pReqMsg = (tpSirEXTScanStartReqParams)
3462 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3465 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 }
3467
3468 pReqMsg->requestId = nla_get_u32(
3469 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3470 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3471
3472 pReqMsg->sessionId = pAdapter->sessionId;
3473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3474
3475 /* Parse and fetch base period */
3476 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3478 goto fail;
3479 }
3480 pReqMsg->basePeriod = nla_get_u32(
3481 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3483 pReqMsg->basePeriod);
3484
3485 /* Parse and fetch max AP per scan */
3486 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3488 goto fail;
3489 }
3490 pReqMsg->maxAPperScan = nla_get_u32(
3491 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3492 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3493 pReqMsg->maxAPperScan);
3494
3495 /* Parse and fetch report threshold */
3496 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3498 goto fail;
3499 }
3500 pReqMsg->reportThreshold = nla_get_u8(
3501 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3502 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3503 pReqMsg->reportThreshold);
3504
3505 /* Parse and fetch number of buckets */
3506 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3508 goto fail;
3509 }
3510 pReqMsg->numBuckets = nla_get_u8(
3511 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3512 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3513 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3514 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3515 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3516 }
3517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3518 pReqMsg->numBuckets);
3519 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3521 goto fail;
3522 }
3523
3524 nla_for_each_nested(buckets,
3525 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3526 if(nla_parse(bucket,
3527 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3528 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3530 goto fail;
3531 }
3532
3533 /* Parse and fetch bucket spec */
3534 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3536 goto fail;
3537 }
3538 bktIndex = nla_get_u8(
3539 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3540 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3541 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3542
3543 /* Parse and fetch wifi band */
3544 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3546 goto fail;
3547 }
3548 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3549 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3550 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3551 pReqMsg->buckets[bktIndex].band);
3552
3553 /* Parse and fetch period */
3554 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3556 goto fail;
3557 }
3558 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3559 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3560 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3561 pReqMsg->buckets[bktIndex].period);
3562
3563 /* Parse and fetch report events */
3564 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3566 goto fail;
3567 }
3568 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3569 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3570 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3571 pReqMsg->buckets[bktIndex].reportEvents);
3572
3573 /* Parse and fetch number of channels */
3574 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3576 goto fail;
3577 }
3578 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3579 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3580 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3581 pReqMsg->buckets[bktIndex].numChannels);
3582
3583 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3585 goto fail;
3586 }
3587
3588 j = 0;
3589 nla_for_each_nested(channels,
3590 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3591 if(nla_parse(channel,
3592 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3593 nla_data(channels), nla_len(channels),
3594 NULL)) { //wlan_hdd_extscan_config_policy here
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3596 goto fail;
3597 }
3598
3599 /* Parse and fetch channel */
3600 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3602 goto fail;
3603 }
3604 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3605 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3606 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3607 pReqMsg->buckets[bktIndex].channels[j].channel);
3608
3609 /* Parse and fetch dwell time */
3610 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3612 goto fail;
3613 }
3614 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3615 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3617 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3618
3619 /* Parse and fetch channel spec passive */
3620 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3621 hddLog(VOS_TRACE_LEVEL_ERROR,
3622 FL("attr channel spec passive failed"));
3623 goto fail;
3624 }
3625 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3626 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3628 pReqMsg->buckets[bktIndex].channels[j].passive);
3629 j++;
3630 }
3631 i++;
3632 }
3633 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3634 if (!HAL_STATUS_SUCCESS(status)) {
3635 hddLog(VOS_TRACE_LEVEL_ERROR,
3636 FL("sme_EXTScanStart failed(err=%d)"), status);
3637 vos_mem_free(pReqMsg);
3638 return -EINVAL;
3639 }
3640
Dino Myclee8843b32014-07-04 14:21:45 +05303641 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642 return 0;
3643
3644fail:
3645 vos_mem_free(pReqMsg);
3646 return -EINVAL;
3647}
3648
3649static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3650 struct wireless_dev *wdev,
3651 void *data, int dataLen)
3652{
Dino Myclee8843b32014-07-04 14:21:45 +05303653 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654 struct net_device *dev = wdev->netdev;
3655 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3656 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3657 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3658 eHalStatus status;
3659
3660 status = wlan_hdd_validate_context(pHddCtx);
3661 if (0 != status)
3662 {
3663 hddLog(VOS_TRACE_LEVEL_ERROR,
3664 FL("HDD context is not valid"));
3665 return -EINVAL;
3666 }
Dino Myclee8843b32014-07-04 14:21:45 +05303667 /* check the EXTScan Capability */
3668 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3669 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3670 {
3671 hddLog(VOS_TRACE_LEVEL_ERROR,
3672 FL("EXTScan not enabled/supported by Firmware"));
3673 return -EINVAL;
3674 }
3675
Dino Mycle6fb96c12014-06-10 11:52:40 +05303676 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3677 data, dataLen,
3678 wlan_hdd_extscan_config_policy)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3680 return -EINVAL;
3681 }
3682
3683 /* Parse and fetch request Id */
3684 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3686 return -EINVAL;
3687 }
3688
Dino Myclee8843b32014-07-04 14:21:45 +05303689 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303690 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303691 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692
Dino Myclee8843b32014-07-04 14:21:45 +05303693 reqMsg.sessionId = pAdapter->sessionId;
3694 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695
Dino Myclee8843b32014-07-04 14:21:45 +05303696 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303697 if (!HAL_STATUS_SUCCESS(status)) {
3698 hddLog(VOS_TRACE_LEVEL_ERROR,
3699 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303700 return -EINVAL;
3701 }
3702
3703 return 0;
3704}
3705
3706static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3707 struct wireless_dev *wdev,
3708 void *data, int dataLen)
3709{
Dino Myclee8843b32014-07-04 14:21:45 +05303710 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 struct net_device *dev = wdev->netdev;
3712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3713 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3714 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3715 eHalStatus status;
3716
3717 status = wlan_hdd_validate_context(pHddCtx);
3718 if (0 != status)
3719 {
3720 hddLog(VOS_TRACE_LEVEL_ERROR,
3721 FL("HDD context is not valid"));
3722 return -EINVAL;
3723 }
Dino Myclee8843b32014-07-04 14:21:45 +05303724 /* check the EXTScan Capability */
3725 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3726 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3727 {
3728 hddLog(VOS_TRACE_LEVEL_ERROR,
3729 FL("EXTScan not enabled/supported by Firmware"));
3730 return -EINVAL;
3731 }
3732
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3734 data, dataLen,
3735 wlan_hdd_extscan_config_policy)) {
3736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3737 return -EINVAL;
3738 }
3739
3740 /* Parse and fetch request Id */
3741 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3743 return -EINVAL;
3744 }
3745
Dino Myclee8843b32014-07-04 14:21:45 +05303746 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303747 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749
Dino Myclee8843b32014-07-04 14:21:45 +05303750 reqMsg.sessionId = pAdapter->sessionId;
3751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303752
Dino Myclee8843b32014-07-04 14:21:45 +05303753 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303754 if (!HAL_STATUS_SUCCESS(status)) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 return -EINVAL;
3758 }
3759
3760 return 0;
3761}
3762
3763static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3764 struct wiphy *wiphy,
3765 struct wireless_dev *wdev,
3766 void *data, int dataLen)
3767{
Dino Myclee8843b32014-07-04 14:21:45 +05303768 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 struct net_device *dev = wdev->netdev;
3770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3772 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3773 eHalStatus status;
3774
3775 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3776 status = wlan_hdd_validate_context(pHddCtx);
3777 if (0 != status)
3778 {
3779 hddLog(VOS_TRACE_LEVEL_ERROR,
3780 FL("HDD context is not valid"));
3781 return -EINVAL;
3782 }
Dino Myclee8843b32014-07-04 14:21:45 +05303783 /* check the EXTScan Capability */
3784 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3785 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("EXTScan not enabled/supported by Firmware"));
3789 return -EINVAL;
3790 }
3791
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3793 data, dataLen,
3794 wlan_hdd_extscan_config_policy)) {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3796 return -EINVAL;
3797 }
3798
3799 /* Parse and fetch request Id */
3800 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3802 return -EINVAL;
3803 }
3804
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303807 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809
Dino Myclee8843b32014-07-04 14:21:45 +05303810 reqMsg.sessionId = pAdapter->sessionId;
3811 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
Dino Myclee8843b32014-07-04 14:21:45 +05303813 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 if (!HAL_STATUS_SUCCESS(status)) {
3815 hddLog(VOS_TRACE_LEVEL_ERROR,
3816 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 return -EINVAL;
3818 }
3819
3820 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3821 return 0;
3822}
3823
3824#endif /* WLAN_FEATURE_EXTSCAN */
3825
Sunil Duttc69bccb2014-05-26 21:30:20 +05303826const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3827{
3828#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3829 {
3830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3833 WIPHY_VENDOR_CMD_NEED_NETDEV |
3834 WIPHY_VENDOR_CMD_NEED_RUNNING,
3835 .doit = wlan_hdd_cfg80211_ll_stats_clear
3836 },
3837
3838 {
3839 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3840 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3841 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3842 WIPHY_VENDOR_CMD_NEED_NETDEV |
3843 WIPHY_VENDOR_CMD_NEED_RUNNING,
3844 .doit = wlan_hdd_cfg80211_ll_stats_set
3845 },
3846
3847 {
3848 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3849 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3850 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3851 WIPHY_VENDOR_CMD_NEED_NETDEV |
3852 WIPHY_VENDOR_CMD_NEED_RUNNING,
3853 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303854 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303855#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303856#ifdef WLAN_FEATURE_EXTSCAN
3857 {
3858 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3859 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3860 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3861 WIPHY_VENDOR_CMD_NEED_NETDEV |
3862 WIPHY_VENDOR_CMD_NEED_RUNNING,
3863 .doit = wlan_hdd_cfg80211_extscan_start
3864 },
3865 {
3866 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3867 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3868 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3869 WIPHY_VENDOR_CMD_NEED_NETDEV |
3870 WIPHY_VENDOR_CMD_NEED_RUNNING,
3871 .doit = wlan_hdd_cfg80211_extscan_stop
3872 },
3873 {
3874 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3875 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3876 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3877 WIPHY_VENDOR_CMD_NEED_NETDEV,
3878 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3879 },
3880 {
3881 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3882 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3883 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3884 WIPHY_VENDOR_CMD_NEED_NETDEV |
3885 WIPHY_VENDOR_CMD_NEED_RUNNING,
3886 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3887 },
3888 {
3889 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3890 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3891 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3892 WIPHY_VENDOR_CMD_NEED_NETDEV |
3893 WIPHY_VENDOR_CMD_NEED_RUNNING,
3894 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3895 },
3896 {
3897 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3898 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3899 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3900 WIPHY_VENDOR_CMD_NEED_NETDEV |
3901 WIPHY_VENDOR_CMD_NEED_RUNNING,
3902 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3903 },
3904 {
3905 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3906 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3907 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3908 WIPHY_VENDOR_CMD_NEED_NETDEV |
3909 WIPHY_VENDOR_CMD_NEED_RUNNING,
3910 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3911 },
3912 {
3913 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3914 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3915 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3916 WIPHY_VENDOR_CMD_NEED_NETDEV |
3917 WIPHY_VENDOR_CMD_NEED_RUNNING,
3918 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3919 },
3920 {
3921 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3922 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3924 WIPHY_VENDOR_CMD_NEED_NETDEV |
3925 WIPHY_VENDOR_CMD_NEED_RUNNING,
3926 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3927 },
3928#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303929};
3930
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003931/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303932static const
3933struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003934{
3935#ifdef FEATURE_WLAN_CH_AVOID
3936 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303937 .vendor_id = QCA_NL80211_VENDOR_ID,
3938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003939 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303940#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3941#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3942 {
3943 /* Index = 1*/
3944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3946 },
3947 {
3948 /* Index = 2*/
3949 .vendor_id = QCA_NL80211_VENDOR_ID,
3950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3951 },
3952 {
3953 /* Index = 3*/
3954 .vendor_id = QCA_NL80211_VENDOR_ID,
3955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3956 },
3957 {
3958 /* Index = 4*/
3959 .vendor_id = QCA_NL80211_VENDOR_ID,
3960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3961 },
3962 {
3963 /* Index = 5*/
3964 .vendor_id = QCA_NL80211_VENDOR_ID,
3965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3966 },
3967 {
3968 /* Index = 6*/
3969 .vendor_id = QCA_NL80211_VENDOR_ID,
3970 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3971 },
3972#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973#ifdef WLAN_FEATURE_EXTSCAN
3974 {
3975 .vendor_id = QCA_NL80211_VENDOR_ID,
3976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3977 },
3978 {
3979 .vendor_id = QCA_NL80211_VENDOR_ID,
3980 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3981 },
3982 {
3983 .vendor_id = QCA_NL80211_VENDOR_ID,
3984 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3985 },
3986 {
3987 .vendor_id = QCA_NL80211_VENDOR_ID,
3988 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3989 },
3990 {
3991 .vendor_id = QCA_NL80211_VENDOR_ID,
3992 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
3993 },
3994 {
3995 .vendor_id = QCA_NL80211_VENDOR_ID,
3996 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
3997 },
3998 {
3999 .vendor_id = QCA_NL80211_VENDOR_ID,
4000 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4001 },
4002 {
4003 .vendor_id = QCA_NL80211_VENDOR_ID,
4004 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4005 },
4006 {
4007 .vendor_id = QCA_NL80211_VENDOR_ID,
4008 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4009 },
4010 {
4011 .vendor_id = QCA_NL80211_VENDOR_ID,
4012 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4013 },
4014 {
4015 .vendor_id = QCA_NL80211_VENDOR_ID,
4016 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4017 },
4018 {
4019 .vendor_id = QCA_NL80211_VENDOR_ID,
4020 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4021 },
4022 {
4023 .vendor_id = QCA_NL80211_VENDOR_ID,
4024 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4025 },
4026#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304027
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004028};
4029
Jeff Johnson295189b2012-06-20 16:38:30 -07004030/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304031 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304032 * This function is called by hdd_wlan_startup()
4033 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304034 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004035 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304036struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004037{
4038 struct wiphy *wiphy;
4039 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304040 /*
4041 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 */
4043 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4044
4045 if (!wiphy)
4046 {
4047 /* Print error and jump into err label and free the memory */
4048 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4049 return NULL;
4050 }
4051
Sunil Duttc69bccb2014-05-26 21:30:20 +05304052
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 return wiphy;
4054}
4055
4056/*
4057 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304058 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004059 * private ioctl to change the band value
4060 */
4061int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4062{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304063 int i, j;
4064 eNVChannelEnabledType channelEnabledState;
4065
Jeff Johnsone7245742012-09-05 17:12:55 -07004066 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304067
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304068 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304070
4071 if (NULL == wiphy->bands[i])
4072 {
4073 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4074 __func__, i);
4075 continue;
4076 }
4077
4078 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4079 {
4080 struct ieee80211_supported_band *band = wiphy->bands[i];
4081
4082 channelEnabledState = vos_nv_getChannelEnabledState(
4083 band->channels[j].hw_value);
4084
4085 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4086 {
4087 // Enable Social channels for P2P
4088 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4089 NV_CHANNEL_ENABLE == channelEnabledState)
4090 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4091 else
4092 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4093 continue;
4094 }
4095 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4096 {
4097 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4098 continue;
4099 }
4100
4101 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4102 NV_CHANNEL_INVALID == channelEnabledState)
4103 {
4104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4105 }
4106 else if (NV_CHANNEL_DFS == channelEnabledState)
4107 {
4108 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4109 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4110 }
4111 else
4112 {
4113 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4114 |IEEE80211_CHAN_RADAR);
4115 }
4116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 }
4118 return 0;
4119}
4120/*
4121 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304122 * This function is called by hdd_wlan_startup()
4123 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 * This function is used to initialize and register wiphy structure.
4125 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304126int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004127 struct wiphy *wiphy,
4128 hdd_config_t *pCfg
4129 )
4130{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304131 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304132 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4133
Jeff Johnsone7245742012-09-05 17:12:55 -07004134 ENTER();
4135
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 /* Now bind the underlying wlan device with wiphy */
4137 set_wiphy_dev(wiphy, dev);
4138
4139 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004140
Kiet Lam6c583332013-10-14 05:37:09 +05304141#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004142 /* the flag for the other case would be initialzed in
4143 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004144 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304145#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004146
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147 /* This will disable updating of NL channels from passive to
4148 * active if a beacon is received on passive channel. */
4149 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004150
Amar Singhalfddc28c2013-09-05 13:03:40 -07004151
Amar Singhala49cbc52013-10-08 18:37:44 -07004152
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004154 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4155 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4156 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004157 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304158 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004159#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004160
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004161#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004162 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004163#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004164 || pCfg->isFastRoamIniFeatureEnabled
4165#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004166#ifdef FEATURE_WLAN_ESE
4167 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004168#endif
4169 )
4170 {
4171 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4172 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004173#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004174#ifdef FEATURE_WLAN_TDLS
4175 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4176 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4177#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304178#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304179 if (pCfg->configPNOScanSupport)
4180 {
4181 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4182 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4183 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4184 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4185 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304186#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004187
Amar Singhalfddc28c2013-09-05 13:03:40 -07004188#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004189 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4190 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004191 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004192 driver need to determine what to do with both
4193 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004194
4195 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004196#else
4197 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004198#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304200 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4201
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304202 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004203
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304204 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4205
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304207 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004208 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4210 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004211 | BIT(NL80211_IFTYPE_AP);
4212
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304213 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004214 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4216 if( pCfg->enableMCC )
4217 {
4218 /* Currently, supports up to two channels */
4219 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004220
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304221 if( !pCfg->allowMCCGODiffBI )
4222 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004223
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304224 }
4225 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4226 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004227#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304228 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004229
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 /* Before registering we need to update the ht capabilitied based
4231 * on ini values*/
4232 if( !pCfg->ShortGI20MhzEnable )
4233 {
4234 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4235 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4236 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4237 }
4238
4239 if( !pCfg->ShortGI40MhzEnable )
4240 {
4241 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4242 }
4243
4244 if( !pCfg->nChannelBondingMode5GHz )
4245 {
4246 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4247 }
4248
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304249 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304250 if (true == hdd_is_5g_supported(pHddCtx))
4251 {
4252 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4253 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304254
4255 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4256 {
4257
4258 if (NULL == wiphy->bands[i])
4259 {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4261 __func__, i);
4262 continue;
4263 }
4264
4265 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4266 {
4267 struct ieee80211_supported_band *band = wiphy->bands[i];
4268
4269 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4270 {
4271 // Enable social channels for P2P
4272 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4273 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4274 else
4275 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4276 continue;
4277 }
4278 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4279 {
4280 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4281 continue;
4282 }
4283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 }
4285 /*Initialise the supported cipher suite details*/
4286 wiphy->cipher_suites = hdd_cipher_suites;
4287 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4288
4289 /*signal strength in mBm (100*dBm) */
4290 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4291
4292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07004293 wiphy->max_remain_on_channel_duration = 1000;
4294#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004295
Sunil Duttc69bccb2014-05-26 21:30:20 +05304296 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4297 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004298 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4299 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4300
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304301 EXIT();
4302 return 0;
4303}
4304
4305/* In this function we are registering wiphy. */
4306int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4307{
4308 ENTER();
4309 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004310 if (0 > wiphy_register(wiphy))
4311 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304312 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004313 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4314 return -EIO;
4315 }
4316
4317 EXIT();
4318 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304319}
Jeff Johnson295189b2012-06-20 16:38:30 -07004320
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304321/* In this function we are updating channel list when,
4322 regulatory domain is FCC and country code is US.
4323 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4324 As per FCC smart phone is not a indoor device.
4325 GO should not opeate on indoor channels */
4326void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4327{
4328 int j;
4329 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4330 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4331 //Default counrtycode from NV at the time of wiphy initialization.
4332 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4333 &defaultCountryCode[0]))
4334 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004335 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304336 }
4337 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4338 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304339 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4340 {
4341 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4342 return;
4343 }
4344 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4345 {
4346 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4347 // Mark UNII -1 band channel as passive
4348 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4349 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4350 }
4351 }
4352}
4353
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304354/* This function registers for all frame which supplicant is interested in */
4355void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004356{
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4358 /* Register for all P2P action, public action etc frames */
4359 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4360
Jeff Johnsone7245742012-09-05 17:12:55 -07004361 ENTER();
4362
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 /* Right now we are registering these frame when driver is getting
4364 initialized. Once we will move to 2.6.37 kernel, in which we have
4365 frame register ops, we will move this code as a part of that */
4366 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304367 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004368 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4369
4370 /* GAS Initial Response */
4371 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4372 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304373
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 /* GAS Comeback Request */
4375 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4376 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4377
4378 /* GAS Comeback Response */
4379 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4380 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4381
4382 /* P2P Public Action */
4383 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304384 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004385 P2P_PUBLIC_ACTION_FRAME_SIZE );
4386
4387 /* P2P Action */
4388 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4389 (v_U8_t*)P2P_ACTION_FRAME,
4390 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004391
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304392 /* WNM BSS Transition Request frame */
4393 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4394 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4395 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004396
4397 /* WNM-Notification */
4398 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4399 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4400 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004401}
4402
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304403void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004404{
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4406 /* Register for all P2P action, public action etc frames */
4407 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4408
Jeff Johnsone7245742012-09-05 17:12:55 -07004409 ENTER();
4410
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 /* Right now we are registering these frame when driver is getting
4412 initialized. Once we will move to 2.6.37 kernel, in which we have
4413 frame register ops, we will move this code as a part of that */
4414 /* GAS Initial Request */
4415
4416 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4417 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4418
4419 /* GAS Initial Response */
4420 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4421 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304422
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 /* GAS Comeback Request */
4424 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4425 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4426
4427 /* GAS Comeback Response */
4428 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4429 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4430
4431 /* P2P Public Action */
4432 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304433 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004434 P2P_PUBLIC_ACTION_FRAME_SIZE );
4435
4436 /* P2P Action */
4437 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4438 (v_U8_t*)P2P_ACTION_FRAME,
4439 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004440 /* WNM-Notification */
4441 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4442 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4443 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004444}
4445
4446#ifdef FEATURE_WLAN_WAPI
4447void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4448 const u8 *mac_addr, u8 *key , int key_Len)
4449{
4450 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4451 tCsrRoamSetKey setKey;
4452 v_BOOL_t isConnected = TRUE;
4453 int status = 0;
4454 v_U32_t roamId= 0xFF;
4455 tANI_U8 *pKeyPtr = NULL;
4456 int n = 0;
4457
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4459 __func__, hdd_device_modetoString(pAdapter->device_mode),
4460 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004461
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304462 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 setKey.keyId = key_index; // Store Key ID
4464 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4465 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4466 setKey.paeRole = 0 ; // the PAE role
4467 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4468 {
4469 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4470 }
4471 else
4472 {
4473 isConnected = hdd_connIsConnected(pHddStaCtx);
4474 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4475 }
4476 setKey.keyLength = key_Len;
4477 pKeyPtr = setKey.Key;
4478 memcpy( pKeyPtr, key, key_Len);
4479
Arif Hussain6d2a3322013-11-17 19:50:10 -08004480 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004481 __func__, key_Len);
4482 for (n = 0 ; n < key_Len; n++)
4483 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4484 __func__,n,setKey.Key[n]);
4485
4486 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4487 if ( isConnected )
4488 {
4489 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4490 pAdapter->sessionId, &setKey, &roamId );
4491 }
4492 if ( status != 0 )
4493 {
4494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4495 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4496 __LINE__, status );
4497 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4498 }
4499}
4500#endif /* FEATURE_WLAN_WAPI*/
4501
4502#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304503int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 beacon_data_t **ppBeacon,
4505 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004506#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304507int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004508 beacon_data_t **ppBeacon,
4509 struct cfg80211_beacon_data *params,
4510 int dtim_period)
4511#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304512{
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 int size;
4514 beacon_data_t *beacon = NULL;
4515 beacon_data_t *old = NULL;
4516 int head_len,tail_len;
4517
Jeff Johnsone7245742012-09-05 17:12:55 -07004518 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004519 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304520 {
4521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4522 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004523 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004525
4526 old = pAdapter->sessionCtx.ap.beacon;
4527
4528 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304529 {
4530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4531 FL("session(%d) old and new heads points to NULL"),
4532 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004533 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304534 }
4535
4536 if (params->tail && !params->tail_len)
4537 {
4538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4539 FL("tail_len is zero but tail is not NULL"));
4540 return -EINVAL;
4541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004542
Jeff Johnson295189b2012-06-20 16:38:30 -07004543#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4544 /* Kernel 3.0 is not updating dtim_period for set beacon */
4545 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304546 {
4547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4548 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304550 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004551#endif
4552
4553 if(params->head)
4554 head_len = params->head_len;
4555 else
4556 head_len = old->head_len;
4557
4558 if(params->tail || !old)
4559 tail_len = params->tail_len;
4560 else
4561 tail_len = old->tail_len;
4562
4563 size = sizeof(beacon_data_t) + head_len + tail_len;
4564
4565 beacon = kzalloc(size, GFP_KERNEL);
4566
4567 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304568 {
4569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4570 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004573
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004574#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 if(params->dtim_period || !old )
4576 beacon->dtim_period = params->dtim_period;
4577 else
4578 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004579#else
4580 if(dtim_period || !old )
4581 beacon->dtim_period = dtim_period;
4582 else
4583 beacon->dtim_period = old->dtim_period;
4584#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304585
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4587 beacon->tail = beacon->head + head_len;
4588 beacon->head_len = head_len;
4589 beacon->tail_len = tail_len;
4590
4591 if(params->head) {
4592 memcpy (beacon->head,params->head,beacon->head_len);
4593 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304594 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004595 if(old)
4596 memcpy (beacon->head,old->head,beacon->head_len);
4597 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304598
Jeff Johnson295189b2012-06-20 16:38:30 -07004599 if(params->tail) {
4600 memcpy (beacon->tail,params->tail,beacon->tail_len);
4601 }
4602 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304603 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004604 memcpy (beacon->tail,old->tail,beacon->tail_len);
4605 }
4606
4607 *ppBeacon = beacon;
4608
4609 kfree(old);
4610
4611 return 0;
4612
4613}
Jeff Johnson295189b2012-06-20 16:38:30 -07004614
4615v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4616{
4617 int left = length;
4618 v_U8_t *ptr = pIes;
4619 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304620
Jeff Johnson295189b2012-06-20 16:38:30 -07004621 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304622 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 elem_id = ptr[0];
4624 elem_len = ptr[1];
4625 left -= 2;
4626 if(elem_len > left)
4627 {
4628 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004629 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 eid,elem_len,left);
4631 return NULL;
4632 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304633 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 {
4635 return ptr;
4636 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304637
Jeff Johnson295189b2012-06-20 16:38:30 -07004638 left -= elem_len;
4639 ptr += (elem_len + 2);
4640 }
4641 return NULL;
4642}
4643
Jeff Johnson295189b2012-06-20 16:38:30 -07004644/* Check if rate is 11g rate or not */
4645static int wlan_hdd_rate_is_11g(u8 rate)
4646{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004647 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 u8 i;
4649 for (i = 0; i < 8; i++)
4650 {
4651 if(rate == gRateArray[i])
4652 return TRUE;
4653 }
4654 return FALSE;
4655}
4656
4657/* Check for 11g rate and set proper 11g only mode */
4658static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4659 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4660{
4661 u8 i, num_rates = pIe[0];
4662
4663 pIe += 1;
4664 for ( i = 0; i < num_rates; i++)
4665 {
4666 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4667 {
4668 /* If rate set have 11g rate than change the mode to 11G */
4669 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4670 if (pIe[i] & BASIC_RATE_MASK)
4671 {
4672 /* If we have 11g rate as basic rate, it means mode
4673 is 11g only mode.
4674 */
4675 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4676 *pCheckRatesfor11g = FALSE;
4677 }
4678 }
4679 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4680 {
4681 *require_ht = TRUE;
4682 }
4683 }
4684 return;
4685}
4686
4687static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4688{
4689 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4690 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4691 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4692 u8 checkRatesfor11g = TRUE;
4693 u8 require_ht = FALSE;
4694 u8 *pIe=NULL;
4695
4696 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4697
4698 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4699 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4700 if (pIe != NULL)
4701 {
4702 pIe += 1;
4703 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4704 &pConfig->SapHw_mode);
4705 }
4706
4707 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4708 WLAN_EID_EXT_SUPP_RATES);
4709 if (pIe != NULL)
4710 {
4711
4712 pIe += 1;
4713 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4714 &pConfig->SapHw_mode);
4715 }
4716
4717 if( pConfig->channel > 14 )
4718 {
4719 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4720 }
4721
4722 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4723 WLAN_EID_HT_CAPABILITY);
4724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304725 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004726 {
4727 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4728 if(require_ht)
4729 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4730 }
4731}
4732
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304733static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4734 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4735{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004736 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304737 v_U8_t *pIe = NULL;
4738 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4739
4740 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4741 pBeacon->tail, pBeacon->tail_len);
4742
4743 if (pIe)
4744 {
4745 ielen = pIe[1] + 2;
4746 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4747 {
4748 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4749 }
4750 else
4751 {
4752 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4753 return -EINVAL;
4754 }
4755 *total_ielen += ielen;
4756 }
4757 return 0;
4758}
4759
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004760static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4761 v_U8_t *genie, v_U8_t *total_ielen)
4762{
4763 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4764 int left = pBeacon->tail_len;
4765 v_U8_t *ptr = pBeacon->tail;
4766 v_U8_t elem_id, elem_len;
4767 v_U16_t ielen = 0;
4768
4769 if ( NULL == ptr || 0 == left )
4770 return;
4771
4772 while (left >= 2)
4773 {
4774 elem_id = ptr[0];
4775 elem_len = ptr[1];
4776 left -= 2;
4777 if (elem_len > left)
4778 {
4779 hddLog( VOS_TRACE_LEVEL_ERROR,
4780 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4781 elem_id, elem_len, left);
4782 return;
4783 }
4784 if (IE_EID_VENDOR == elem_id)
4785 {
4786 /* skipping the VSIE's which we don't want to include or
4787 * it will be included by existing code
4788 */
4789 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4790#ifdef WLAN_FEATURE_WFD
4791 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4792#endif
4793 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4794 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4795 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4796 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4797 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4798 {
4799 ielen = ptr[1] + 2;
4800 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4801 {
4802 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4803 *total_ielen += ielen;
4804 }
4805 else
4806 {
4807 hddLog( VOS_TRACE_LEVEL_ERROR,
4808 "IE Length is too big "
4809 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4810 elem_id, elem_len, *total_ielen);
4811 }
4812 }
4813 }
4814
4815 left -= elem_len;
4816 ptr += (elem_len + 2);
4817 }
4818 return;
4819}
4820
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004821#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004822static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4823 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004824#else
4825static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4826 struct cfg80211_beacon_data *params)
4827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004828{
4829 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304830 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004832 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004833
4834 genie = vos_mem_malloc(MAX_GENIE_LEN);
4835
4836 if(genie == NULL) {
4837
4838 return -ENOMEM;
4839 }
4840
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304841 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4842 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304844 hddLog(LOGE,
4845 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304846 ret = -EINVAL;
4847 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 }
4849
4850#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304851 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4852 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4853 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304854 hddLog(LOGE,
4855 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304856 ret = -EINVAL;
4857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004858 }
4859#endif
4860
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304861 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4862 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304864 hddLog(LOGE,
4865 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304866 ret = -EINVAL;
4867 goto done;
4868 }
4869
4870 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4871 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004872 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004874
4875 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4876 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4877 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4878 {
4879 hddLog(LOGE,
4880 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004881 ret = -EINVAL;
4882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004883 }
4884
4885 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4886 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4887 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4888 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4889 ==eHAL_STATUS_FAILURE)
4890 {
4891 hddLog(LOGE,
4892 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004893 ret = -EINVAL;
4894 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004895 }
4896
4897 // Added for ProResp IE
4898 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4899 {
4900 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4901 u8 probe_rsp_ie_len[3] = {0};
4902 u8 counter = 0;
4903 /* Check Probe Resp Length if it is greater then 255 then Store
4904 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4905 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4906 Store More then 255 bytes into One Variable.
4907 */
4908 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4909 {
4910 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4911 {
4912 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4913 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4914 }
4915 else
4916 {
4917 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4918 rem_probe_resp_ie_len = 0;
4919 }
4920 }
4921
4922 rem_probe_resp_ie_len = 0;
4923
4924 if (probe_rsp_ie_len[0] > 0)
4925 {
4926 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4927 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4928 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4929 probe_rsp_ie_len[0], NULL,
4930 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4931 {
4932 hddLog(LOGE,
4933 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004934 ret = -EINVAL;
4935 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 }
4937 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4938 }
4939
4940 if (probe_rsp_ie_len[1] > 0)
4941 {
4942 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4943 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4944 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4945 probe_rsp_ie_len[1], NULL,
4946 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4947 {
4948 hddLog(LOGE,
4949 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004950 ret = -EINVAL;
4951 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 }
4953 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4954 }
4955
4956 if (probe_rsp_ie_len[2] > 0)
4957 {
4958 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4959 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4960 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4961 probe_rsp_ie_len[2], NULL,
4962 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4963 {
4964 hddLog(LOGE,
4965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004966 ret = -EINVAL;
4967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 }
4969 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4970 }
4971
4972 if (probe_rsp_ie_len[1] == 0 )
4973 {
4974 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4975 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4976 eANI_BOOLEAN_FALSE) )
4977 {
4978 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004979 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 }
4981 }
4982
4983 if (probe_rsp_ie_len[2] == 0 )
4984 {
4985 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4986 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4987 eANI_BOOLEAN_FALSE) )
4988 {
4989 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004990 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 }
4992 }
4993
4994 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4995 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4996 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4997 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4998 == eHAL_STATUS_FAILURE)
4999 {
5000 hddLog(LOGE,
5001 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005002 ret = -EINVAL;
5003 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 }
5005 }
5006 else
5007 {
5008 // Reset WNI_CFG_PROBE_RSP Flags
5009 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5010
5011 hddLog(VOS_TRACE_LEVEL_INFO,
5012 "%s: No Probe Response IE received in set beacon",
5013 __func__);
5014 }
5015
5016 // Added for AssocResp IE
5017 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5018 {
5019 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5020 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5021 params->assocresp_ies_len, NULL,
5022 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5023 {
5024 hddLog(LOGE,
5025 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005026 ret = -EINVAL;
5027 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 }
5029
5030 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5031 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5032 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5033 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5034 == eHAL_STATUS_FAILURE)
5035 {
5036 hddLog(LOGE,
5037 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005038 ret = -EINVAL;
5039 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 }
5041 }
5042 else
5043 {
5044 hddLog(VOS_TRACE_LEVEL_INFO,
5045 "%s: No Assoc Response IE received in set beacon",
5046 __func__);
5047
5048 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5049 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5050 eANI_BOOLEAN_FALSE) )
5051 {
5052 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005053 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 }
5055 }
5056
Jeff Johnsone7245742012-09-05 17:12:55 -07005057done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305059 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005060}
Jeff Johnson295189b2012-06-20 16:38:30 -07005061
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305062/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 * FUNCTION: wlan_hdd_validate_operation_channel
5064 * called by wlan_hdd_cfg80211_start_bss() and
5065 * wlan_hdd_cfg80211_set_channel()
5066 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305067 * channel list.
5068 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005069VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005070{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305071
Jeff Johnson295189b2012-06-20 16:38:30 -07005072 v_U32_t num_ch = 0;
5073 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5074 u32 indx = 0;
5075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305076 v_U8_t fValidChannel = FALSE, count = 0;
5077 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5080
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305081 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305083 /* Validate the channel */
5084 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305086 if ( channel == rfChannels[count].channelNum )
5087 {
5088 fValidChannel = TRUE;
5089 break;
5090 }
5091 }
5092 if (fValidChannel != TRUE)
5093 {
5094 hddLog(VOS_TRACE_LEVEL_ERROR,
5095 "%s: Invalid Channel [%d]", __func__, channel);
5096 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 }
5098 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305099 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305101 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5102 valid_ch, &num_ch))
5103 {
5104 hddLog(VOS_TRACE_LEVEL_ERROR,
5105 "%s: failed to get valid channel list", __func__);
5106 return VOS_STATUS_E_FAILURE;
5107 }
5108 for (indx = 0; indx < num_ch; indx++)
5109 {
5110 if (channel == valid_ch[indx])
5111 {
5112 break;
5113 }
5114 }
5115
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305116 if (indx >= num_ch)
5117 {
5118 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5119 {
5120 eCsrBand band;
5121 unsigned int freq;
5122
5123 sme_GetFreqBand(hHal, &band);
5124
5125 if (eCSR_BAND_5G == band)
5126 {
5127#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5128 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5129 {
5130 freq = ieee80211_channel_to_frequency(channel,
5131 IEEE80211_BAND_2GHZ);
5132 }
5133 else
5134 {
5135 freq = ieee80211_channel_to_frequency(channel,
5136 IEEE80211_BAND_5GHZ);
5137 }
5138#else
5139 freq = ieee80211_channel_to_frequency(channel);
5140#endif
5141 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5142 return VOS_STATUS_SUCCESS;
5143 }
5144 }
5145
5146 hddLog(VOS_TRACE_LEVEL_ERROR,
5147 "%s: Invalid Channel [%d]", __func__, channel);
5148 return VOS_STATUS_E_FAILURE;
5149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305151
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153
Jeff Johnson295189b2012-06-20 16:38:30 -07005154}
5155
Viral Modi3a32cc52013-02-08 11:14:52 -08005156/**
5157 * FUNCTION: wlan_hdd_cfg80211_set_channel
5158 * This function is used to set the channel number
5159 */
5160static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5161 struct ieee80211_channel *chan,
5162 enum nl80211_channel_type channel_type
5163 )
5164{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305165 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005166 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005167 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005168 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305169 hdd_context_t *pHddCtx;
5170 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005171
5172 ENTER();
5173
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305174
Viral Modi3a32cc52013-02-08 11:14:52 -08005175 if( NULL == dev )
5176 {
5177 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005178 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005179 return -ENODEV;
5180 }
5181 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5184 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5185 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005186 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305187 "%s: device_mode = %s (%d) freq = %d", __func__,
5188 hdd_device_modetoString(pAdapter->device_mode),
5189 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305190
5191 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5192 status = wlan_hdd_validate_context(pHddCtx);
5193
5194 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005195 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5197 "%s: HDD context is not valid", __func__);
5198 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005199 }
5200
5201 /*
5202 * Do freq to chan conversion
5203 * TODO: for 11a
5204 */
5205
5206 channel = ieee80211_frequency_to_channel(freq);
5207
5208 /* Check freq range */
5209 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5210 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5211 {
5212 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005213 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005214 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5215 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5216 return -EINVAL;
5217 }
5218
5219 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5220
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305221 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5222 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005223 {
5224 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5225 {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005227 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5231 "%s: set channel to [%d] for device mode =%d",
5232 __func__, channel,pAdapter->device_mode);
5233 }
5234 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005235 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005236 )
5237 {
5238 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5239 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5241
5242 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5243 {
5244 /* Link is up then return cant set channel*/
5245 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005246 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005247 return -EINVAL;
5248 }
5249
5250 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5251 pHddStaCtx->conn_info.operationChannel = channel;
5252 pRoamProfile->ChannelInfo.ChannelList =
5253 &pHddStaCtx->conn_info.operationChannel;
5254 }
5255 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005256 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005257 )
5258 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305259 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5260 {
5261 if(VOS_STATUS_SUCCESS !=
5262 wlan_hdd_validate_operation_channel(pAdapter,channel))
5263 {
5264 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005265 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305266 return -EINVAL;
5267 }
5268 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5269 }
5270 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005271 {
5272 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5273
5274 /* If auto channel selection is configured as enable/ 1 then ignore
5275 channel set by supplicant
5276 */
5277 if ( cfg_param->apAutoChannelSelection )
5278 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305279 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5280 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005281 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305282 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5283 __func__, hdd_device_modetoString(pAdapter->device_mode),
5284 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005285 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305286 else
5287 {
5288 if(VOS_STATUS_SUCCESS !=
5289 wlan_hdd_validate_operation_channel(pAdapter,channel))
5290 {
5291 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005292 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305293 return -EINVAL;
5294 }
5295 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5296 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005297 }
5298 }
5299 else
5300 {
5301 hddLog(VOS_TRACE_LEVEL_FATAL,
5302 "%s: Invalid device mode failed to set valid channel", __func__);
5303 return -EINVAL;
5304 }
5305 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305306 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005307}
5308
Jeff Johnson295189b2012-06-20 16:38:30 -07005309#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5310static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5311 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005312#else
5313static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5314 struct cfg80211_beacon_data *params,
5315 const u8 *ssid, size_t ssid_len,
5316 enum nl80211_hidden_ssid hidden_ssid)
5317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005318{
5319 tsap_Config_t *pConfig;
5320 beacon_data_t *pBeacon = NULL;
5321 struct ieee80211_mgmt *pMgmt_frame;
5322 v_U8_t *pIe=NULL;
5323 v_U16_t capab_info;
5324 eCsrAuthType RSNAuthType;
5325 eCsrEncryptionType RSNEncryptType;
5326 eCsrEncryptionType mcRSNEncryptType;
5327 int status = VOS_STATUS_SUCCESS;
5328 tpWLAN_SAPEventCB pSapEventCallback;
5329 hdd_hostapd_state_t *pHostapdState;
5330 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5331 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305332 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305334 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005336 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005337 v_BOOL_t MFPCapable = VOS_FALSE;
5338 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305339 eHddDot11Mode sapDot11Mode =
5340 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005341
5342 ENTER();
5343
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305344 iniConfig = pHddCtx->cfg_ini;
5345
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5347
5348 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5349
5350 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5351
5352 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5353
5354 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5355
5356 //channel is already set in the set_channel Call back
5357 //pConfig->channel = pCommitConfig->channel;
5358
5359 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305360 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5362
5363 pConfig->dtim_period = pBeacon->dtim_period;
5364
Arif Hussain6d2a3322013-11-17 19:50:10 -08005365 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 pConfig->dtim_period);
5367
5368
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005369 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005370 {
5371 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305373 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5374 {
5375 tANI_BOOLEAN restartNeeded;
5376 pConfig->ieee80211d = 1;
5377 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5378 sme_setRegInfo(hHal, pConfig->countryCode);
5379 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5380 }
5381 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005383 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005384 pConfig->ieee80211d = 1;
5385 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5386 sme_setRegInfo(hHal, pConfig->countryCode);
5387 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005389 else
5390 {
5391 pConfig->ieee80211d = 0;
5392 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305393 /*
5394 * If auto channel is configured i.e. channel is 0,
5395 * so skip channel validation.
5396 */
5397 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5398 {
5399 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5400 {
5401 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005402 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305403 return -EINVAL;
5404 }
5405 }
5406 else
5407 {
5408 if(1 != pHddCtx->is_dynamic_channel_range_set)
5409 {
5410 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5411 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5412 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5413 }
5414 pHddCtx->is_dynamic_channel_range_set = 0;
5415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005416 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005417 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 {
5419 pConfig->ieee80211d = 0;
5420 }
5421 pConfig->authType = eSAP_AUTO_SWITCH;
5422
5423 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305424
5425 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5427
5428 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5429
5430 /*Set wps station to configured*/
5431 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5432
5433 if(pIe)
5434 {
5435 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5436 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005437 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 return -EINVAL;
5439 }
5440 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5441 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005442 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 /* Check 15 bit of WPS IE as it contain information for wps state
5444 * WPS state
5445 */
5446 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5447 {
5448 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5449 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5450 {
5451 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5452 }
5453 }
5454 }
5455 else
5456 {
5457 pConfig->wps_state = SAP_WPS_DISABLED;
5458 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305459 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005460
c_hpothufe599e92014-06-16 11:38:55 +05305461 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5462 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5463 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5464 eCSR_ENCRYPT_TYPE_NONE;
5465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 pConfig->RSNWPAReqIELength = 0;
5467 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305468 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 WLAN_EID_RSN);
5470 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5473 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5474 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 /* The actual processing may eventually be more extensive than
5476 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 * by the app.
5478 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305479 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5481 &RSNEncryptType,
5482 &mcRSNEncryptType,
5483 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005484 &MFPCapable,
5485 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 pConfig->pRSNWPAReqIE[1]+2,
5487 pConfig->pRSNWPAReqIE );
5488
5489 if( VOS_STATUS_SUCCESS == status )
5490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 /* Now copy over all the security attributes you have
5492 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 * */
5494 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5495 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5496 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5497 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305498 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005499 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5501 }
5502 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5505 pBeacon->tail, pBeacon->tail_len);
5506
5507 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5508 {
5509 if (pConfig->pRSNWPAReqIE)
5510 {
5511 /*Mixed mode WPA/WPA2*/
5512 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5513 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5514 }
5515 else
5516 {
5517 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5518 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5519 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5522 &RSNEncryptType,
5523 &mcRSNEncryptType,
5524 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005525 &MFPCapable,
5526 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 pConfig->pRSNWPAReqIE[1]+2,
5528 pConfig->pRSNWPAReqIE );
5529
5530 if( VOS_STATUS_SUCCESS == status )
5531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305532 /* Now copy over all the security attributes you have
5533 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 * */
5535 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5536 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5537 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5538 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305539 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005540 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5542 }
5543 }
5544 }
5545
Jeff Johnson4416a782013-03-25 14:17:50 -07005546 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5547 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5548 return -EINVAL;
5549 }
5550
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005553#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 if (params->ssid != NULL)
5555 {
5556 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5557 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5558 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5559 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5560 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005561#else
5562 if (ssid != NULL)
5563 {
5564 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5565 pConfig->SSIDinfo.ssid.length = ssid_len;
5566 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5567 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5568 }
5569#endif
5570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305573
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 /* default value */
5575 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5576 pConfig->num_accept_mac = 0;
5577 pConfig->num_deny_mac = 0;
5578
5579 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5580 pBeacon->tail, pBeacon->tail_len);
5581
5582 /* pIe for black list is following form:
5583 type : 1 byte
5584 length : 1 byte
5585 OUI : 4 bytes
5586 acl type : 1 byte
5587 no of mac addr in black list: 1 byte
5588 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589 */
5590 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 {
5592 pConfig->SapMacaddr_acl = pIe[6];
5593 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005594 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305596 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5597 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5599 for (i = 0; i < pConfig->num_deny_mac; i++)
5600 {
5601 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5602 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305603 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 }
5605 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5606 pBeacon->tail, pBeacon->tail_len);
5607
5608 /* pIe for white list is following form:
5609 type : 1 byte
5610 length : 1 byte
5611 OUI : 4 bytes
5612 acl type : 1 byte
5613 no of mac addr in white list: 1 byte
5614 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 */
5616 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 {
5618 pConfig->SapMacaddr_acl = pIe[6];
5619 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005620 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305622 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5623 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5625 for (i = 0; i < pConfig->num_accept_mac; i++)
5626 {
5627 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5628 acl_entry++;
5629 }
5630 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305631
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5633
Jeff Johnsone7245742012-09-05 17:12:55 -07005634#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005635 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305636 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5637 * 11ac in .ini and 11ac is supported by both host and firmware.
5638 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5639 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005640 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5641 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305642 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5643 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5644 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5645 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5646 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005647 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305648 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005649 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305650 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005651
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305652 /* If ACS disable and selected channel <= 14
5653 * OR
5654 * ACS enabled and ACS operating band is choosen as 2.4
5655 * AND
5656 * VHT in 2.4G Disabled
5657 * THEN
5658 * Fallback to 11N mode
5659 */
5660 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5661 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305662 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305663 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005664 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305665 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5666 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005667 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5668 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005669 }
5670#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005672 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5673 {
5674 sme_SelectCBMode(hHal,
5675 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5676 pConfig->channel);
5677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 // ht_capab is not what the name conveys,this is used for protection bitmap
5679 pConfig->ht_capab =
5680 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5681
5682 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5683 {
5684 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5685 return -EINVAL;
5686 }
5687
5688 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305689 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5691 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305692 pConfig->obssProtEnabled =
5693 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005694
Chet Lanctot8cecea22014-02-11 19:09:36 -08005695#ifdef WLAN_FEATURE_11W
5696 pConfig->mfpCapable = MFPCapable;
5697 pConfig->mfpRequired = MFPRequired;
5698 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5699 pConfig->mfpCapable, pConfig->mfpRequired);
5700#endif
5701
Arif Hussain6d2a3322013-11-17 19:50:10 -08005702 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005704 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5705 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5706 (int)pConfig->channel);
5707 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5708 pConfig->SapHw_mode, pConfig->privacy,
5709 pConfig->authType);
5710 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5711 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5712 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5713 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005714
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305715 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 {
5717 //Bss already started. just return.
5718 //TODO Probably it should update some beacon params.
5719 hddLog( LOGE, "Bss Already started...Ignore the request");
5720 EXIT();
5721 return 0;
5722 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 pConfig->persona = pHostapdAdapter->device_mode;
5725
5726 pSapEventCallback = hdd_hostapd_SAPEventCB;
5727 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5728 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5729 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005730 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 return -EINVAL;
5732 }
5733
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305734 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5736
5737 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305738
Jeff Johnson295189b2012-06-20 16:38:30 -07005739 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305740 {
5741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005742 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005743 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 VOS_ASSERT(0);
5745 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305746
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
5748
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005749#ifdef WLAN_FEATURE_P2P_DEBUG
5750 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5751 {
5752 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5753 {
5754 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5755 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005756 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005757 }
5758 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5759 {
5760 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5761 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005762 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005763 }
5764 }
5765#endif
5766
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 pHostapdState->bCommit = TRUE;
5768 EXIT();
5769
5770 return 0;
5771}
5772
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005773#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305774static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5775 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 struct beacon_parameters *params)
5777{
5778 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305779 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305780 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005781
5782 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305783
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5785 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5786 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305787 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5788 hdd_device_modetoString(pAdapter->device_mode),
5789 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5792 status = wlan_hdd_validate_context(pHddCtx);
5793
5794 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5797 "%s: HDD context is not valid", __func__);
5798 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005799 }
5800
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 )
5804 {
5805 beacon_data_t *old,*new;
5806
5807 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305808
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305810 {
5811 hddLog(VOS_TRACE_LEVEL_WARN,
5812 FL("already beacon info added to session(%d)"),
5813 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305815 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005816
5817 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5818
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 {
5821 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005822 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 return -EINVAL;
5824 }
5825
5826 pAdapter->sessionCtx.ap.beacon = new;
5827
5828 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5829 }
5830
5831 EXIT();
5832 return status;
5833}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834
5835static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 struct net_device *dev,
5837 struct beacon_parameters *params)
5838{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305839 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305840 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5841 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305842 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005843
5844 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5846 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5847 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5848 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5849 __func__, hdd_device_modetoString(pAdapter->device_mode),
5850 pAdapter->device_mode);
5851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5853 status = wlan_hdd_validate_context(pHddCtx);
5854
5855 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005856 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5858 "%s: HDD context is not valid", __func__);
5859 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005860 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305861
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305862 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 {
5866 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305869
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305871 {
5872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5873 FL("session(%d) old and new heads points to NULL"),
5874 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005877
5878 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5879
5880 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005882 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 return -EINVAL;
5884 }
5885
5886 pAdapter->sessionCtx.ap.beacon = new;
5887
5888 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5889 }
5890
5891 EXIT();
5892 return status;
5893}
5894
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005895#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5896
5897#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005898static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5899 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005900#else
5901static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5902 struct net_device *dev)
5903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005904{
5905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005906 hdd_context_t *pHddCtx = NULL;
5907 hdd_scaninfo_t *pScanInfo = NULL;
5908 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305909 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305910 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
5912 ENTER();
5913
5914 if (NULL == pAdapter)
5915 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005917 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 return -ENODEV;
5919 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005920
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5922 TRACE_CODE_HDD_CFG80211_STOP_AP,
5923 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305924 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5925 status = wlan_hdd_validate_context(pHddCtx);
5926
5927 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005928 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5930 "%s: HDD context is not valid", __func__);
5931 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005932 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005933
5934 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5935 if (NULL == staAdapter)
5936 {
5937 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5938 if (NULL == staAdapter)
5939 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5941 "%s: HDD adapter context for STA/P2P-CLI is Null",
5942 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005943 }
5944 }
5945
5946 pScanInfo = &pHddCtx->scan_info;
5947
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5949 __func__, hdd_device_modetoString(pAdapter->device_mode),
5950 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005951
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305952 ret = wlan_hdd_scan_abort(pAdapter);
5953
Girish Gowli4bf7a632014-06-12 13:42:11 +05305954 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005955 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5957 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305958
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305959 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005960 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5962 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005963
Jeff Johnsone7245742012-09-05 17:12:55 -07005964 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305965 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005966 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305967 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005968 }
5969
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305970 hdd_hostapd_stop(dev);
5971
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 )
5975 {
5976 beacon_data_t *old;
5977
5978 old = pAdapter->sessionCtx.ap.beacon;
5979
5980 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305981 {
5982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5983 FL("session(%d) beacon data points to NULL"),
5984 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005987
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005989
5990 mutex_lock(&pHddCtx->sap_lock);
5991 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
5992 {
Jeff Johnson4416a782013-03-25 14:17:50 -07005993 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 {
5995 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5996
5997 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
5998
5999 if (!VOS_IS_STATUS_SUCCESS(status))
6000 {
6001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006002 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306004 }
6005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6007 }
6008 mutex_unlock(&pHddCtx->sap_lock);
6009
6010 if(status != VOS_STATUS_SUCCESS)
6011 {
6012 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006013 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 return -EINVAL;
6015 }
6016
Jeff Johnson4416a782013-03-25 14:17:50 -07006017 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6019 ==eHAL_STATUS_FAILURE)
6020 {
6021 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006022 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 }
6024
Jeff Johnson4416a782013-03-25 14:17:50 -07006025 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6027 eANI_BOOLEAN_FALSE) )
6028 {
6029 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006030 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 }
6032
6033 // Reset WNI_CFG_PROBE_RSP Flags
6034 wlan_hdd_reset_prob_rspies(pAdapter);
6035
6036 pAdapter->sessionCtx.ap.beacon = NULL;
6037 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006038#ifdef WLAN_FEATURE_P2P_DEBUG
6039 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6040 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6041 {
6042 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6043 "GO got removed");
6044 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6045 }
6046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 }
6048 EXIT();
6049 return status;
6050}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006051
6052#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6053
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306054static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6055 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006056 struct cfg80211_ap_settings *params)
6057{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306058 hdd_adapter_t *pAdapter;
6059 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306060 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006061
6062 ENTER();
6063
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306064 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006065 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306067 "%s: Device is Null", __func__);
6068 return -ENODEV;
6069 }
6070
6071 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6072 if (NULL == pAdapter)
6073 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306075 "%s: HDD adapter is Null", __func__);
6076 return -ENODEV;
6077 }
6078
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6080 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6081 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306082 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6083 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306085 "%s: HDD adapter magic is invalid", __func__);
6086 return -ENODEV;
6087 }
6088
6089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306090 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306091
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306092 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6095 "%s: HDD context is not valid", __func__);
6096 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306097 }
6098
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306099 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6100 __func__, hdd_device_modetoString(pAdapter->device_mode),
6101 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306102
6103 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006104 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006105 )
6106 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306107 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006108
6109 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306110
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006111 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306112 {
6113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6114 FL("already beacon info added to session(%d)"),
6115 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006116 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306117 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006118
6119 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6120
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306121 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006122 {
6123 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306124 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006125 return -EINVAL;
6126 }
6127 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006129 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6130#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6131 params->channel, params->channel_type);
6132#else
6133 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6134#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006135#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006136 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6137 params->ssid_len, params->hidden_ssid);
6138 }
6139
6140 EXIT();
6141 return status;
6142}
6143
6144
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306145static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006146 struct net_device *dev,
6147 struct cfg80211_beacon_data *params)
6148{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306150 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306151 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006152
6153 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306154
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306155 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6156 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6157 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006159 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306160
6161 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6162 status = wlan_hdd_validate_context(pHddCtx);
6163
6164 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006165 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6167 "%s: HDD context is not valid", __func__);
6168 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006169 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006170
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006172 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306173 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006174 {
6175 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306176
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006177 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006179 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306180 {
6181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6182 FL("session(%d) beacon data points to NULL"),
6183 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006184 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306185 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006186
6187 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6188
6189 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306190 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006191 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006192 return -EINVAL;
6193 }
6194
6195 pAdapter->sessionCtx.ap.beacon = new;
6196
6197 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6198 }
6199
6200 EXIT();
6201 return status;
6202}
6203
6204#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6205
Jeff Johnson295189b2012-06-20 16:38:30 -07006206
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306207static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 struct net_device *dev,
6209 struct bss_parameters *params)
6210{
6211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6212
6213 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306214
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306215 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6216 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6217 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6219 __func__, hdd_device_modetoString(pAdapter->device_mode),
6220 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006221
6222 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 {
6226 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6227 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306228 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 {
6230 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 }
6233
6234 EXIT();
6235 return 0;
6236}
6237
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306238static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6239 struct net_device *dev,
6240 struct bss_parameters *params)
6241{
6242 int ret;
6243
6244 vos_ssr_protect(__func__);
6245 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6246 vos_ssr_unprotect(__func__);
6247
6248 return ret;
6249}
Kiet Lam10841362013-11-01 11:36:50 +05306250/* FUNCTION: wlan_hdd_change_country_code_cd
6251* to wait for contry code completion
6252*/
6253void* wlan_hdd_change_country_code_cb(void *pAdapter)
6254{
6255 hdd_adapter_t *call_back_pAdapter = pAdapter;
6256 complete(&call_back_pAdapter->change_country_code);
6257 return NULL;
6258}
6259
Jeff Johnson295189b2012-06-20 16:38:30 -07006260/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306261 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6263 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306264int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 struct net_device *ndev,
6266 enum nl80211_iftype type,
6267 u32 *flags,
6268 struct vif_params *params
6269 )
6270{
6271 struct wireless_dev *wdev;
6272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006273 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006274 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 tCsrRoamProfile *pRoamProfile = NULL;
6276 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306277 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 eMib_dot11DesiredBssType connectedBssType;
6279 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306280 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006281
6282 ENTER();
6283
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306284 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006285 {
6286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6287 "%s: Adapter context is null", __func__);
6288 return VOS_STATUS_E_FAILURE;
6289 }
6290
6291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6292 if (!pHddCtx)
6293 {
6294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6295 "%s: HDD context is null", __func__);
6296 return VOS_STATUS_E_FAILURE;
6297 }
6298
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306299 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6300 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6301 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306302 status = wlan_hdd_validate_context(pHddCtx);
6303
6304 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6307 "%s: HDD context is not valid", __func__);
6308 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 }
6310
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306311 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6312 __func__, hdd_device_modetoString(pAdapter->device_mode),
6313 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006314
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306315 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 wdev = ndev->ieee80211_ptr;
6317
6318#ifdef WLAN_BTAMP_FEATURE
6319 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6320 (NL80211_IFTYPE_ADHOC == type)||
6321 (NL80211_IFTYPE_AP == type)||
6322 (NL80211_IFTYPE_P2P_GO == type))
6323 {
6324 pHddCtx->isAmpAllowed = VOS_FALSE;
6325 // stop AMP traffic
6326 status = WLANBAP_StopAmp();
6327 if(VOS_STATUS_SUCCESS != status )
6328 {
6329 pHddCtx->isAmpAllowed = VOS_TRUE;
6330 hddLog(VOS_TRACE_LEVEL_FATAL,
6331 "%s: Failed to stop AMP", __func__);
6332 return -EINVAL;
6333 }
6334 }
6335#endif //WLAN_BTAMP_FEATURE
6336 /* Reset the current device mode bit mask*/
6337 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6338
6339 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006341 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 )
6343 {
6344 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006345 if (!pWextState)
6346 {
6347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6348 "%s: pWextState is null", __func__);
6349 return VOS_STATUS_E_FAILURE;
6350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 pRoamProfile = &pWextState->roamProfile;
6352 LastBSSType = pRoamProfile->BSSType;
6353
6354 switch (type)
6355 {
6356 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 hddLog(VOS_TRACE_LEVEL_INFO,
6359 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6360 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006361#ifdef WLAN_FEATURE_11AC
6362 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6363 {
6364 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6365 }
6366#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306367 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006368 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006370 //Check for sub-string p2p to confirm its a p2p interface
6371 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306372 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006373 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6374 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6375 }
6376 else
6377 {
6378 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006380 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306381#ifdef FEATURE_WLAN_TDLS
6382 /* The open adapter for the p2p shall skip initializations in
6383 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6384 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6385 * tdls_init when the change_iface sets the device mode to
6386 * WLAN_HDD_P2P_CLIENT.
6387 */
6388
6389 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6390 {
6391 if (0 != wlan_hdd_tdls_init (pAdapter))
6392 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306393 hddLog(VOS_TRACE_LEVEL_ERROR,
6394 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306395 return -EINVAL;
6396 }
6397 }
6398#endif
6399
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 break;
6401 case NL80211_IFTYPE_ADHOC:
6402 hddLog(VOS_TRACE_LEVEL_INFO,
6403 "%s: setting interface Type to ADHOC", __func__);
6404 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6405 pRoamProfile->phyMode =
6406 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006407 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 wdev->iftype = type;
6409 break;
6410
6411 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 {
6414 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6415 "%s: setting interface Type to %s", __func__,
6416 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6417
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006418 //Cancel any remain on channel for GO mode
6419 if (NL80211_IFTYPE_P2P_GO == type)
6420 {
6421 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6422 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006423 if (NL80211_IFTYPE_AP == type)
6424 {
6425 /* As Loading WLAN Driver one interface being created for p2p device
6426 * address. This will take one HW STA and the max number of clients
6427 * that can connect to softAP will be reduced by one. so while changing
6428 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6429 * interface as it is not required in SoftAP mode.
6430 */
6431
6432 // Get P2P Adapter
6433 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6434
6435 if (pP2pAdapter)
6436 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306437 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006438 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6439 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6440 }
6441 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306442 //Disable IMPS & BMPS for SAP/GO
6443 if(VOS_STATUS_E_FAILURE ==
6444 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6445 {
6446 //Fail to Exit BMPS
6447 VOS_ASSERT(0);
6448 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306449#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006450
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306451 /* A Mutex Lock is introduced while changing the mode to
6452 * protect the concurrent access for the Adapters by TDLS
6453 * module.
6454 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306455 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306458 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 hdd_deinit_adapter( pHddCtx, pAdapter );
6460 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6462 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306463#ifdef FEATURE_WLAN_TDLS
6464 mutex_unlock(&pHddCtx->tdls_lock);
6465#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006466 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6467 (pConfig->apRandomBssidEnabled))
6468 {
6469 /* To meet Android requirements create a randomized
6470 MAC address of the form 02:1A:11:Fx:xx:xx */
6471 get_random_bytes(&ndev->dev_addr[3], 3);
6472 ndev->dev_addr[0] = 0x02;
6473 ndev->dev_addr[1] = 0x1A;
6474 ndev->dev_addr[2] = 0x11;
6475 ndev->dev_addr[3] |= 0xF0;
6476 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6477 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006478 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6479 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006480 }
6481
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 hdd_set_ap_ops( pAdapter->dev );
6483
Kiet Lam10841362013-11-01 11:36:50 +05306484 /* This is for only SAP mode where users can
6485 * control country through ini.
6486 * P2P GO follows station country code
6487 * acquired during the STA scanning. */
6488 if((NL80211_IFTYPE_AP == type) &&
6489 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6490 {
6491 int status = 0;
6492 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6493 "%s: setting country code from INI ", __func__);
6494 init_completion(&pAdapter->change_country_code);
6495 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6496 (void *)(tSmeChangeCountryCallback)
6497 wlan_hdd_change_country_code_cb,
6498 pConfig->apCntryCode, pAdapter,
6499 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306500 eSIR_FALSE,
6501 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306502 if (eHAL_STATUS_SUCCESS == status)
6503 {
6504 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306505 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306506 &pAdapter->change_country_code,
6507 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306508 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306509 {
6510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306511 FL("SME Timed out while setting country code %ld"),
6512 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006513
6514 if (pHddCtx->isLogpInProgress)
6515 {
6516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6517 "%s: LOGP in Progress. Ignore!!!", __func__);
6518 return -EAGAIN;
6519 }
Kiet Lam10841362013-11-01 11:36:50 +05306520 }
6521 }
6522 else
6523 {
6524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006525 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306526 return -EINVAL;
6527 }
6528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006529 status = hdd_init_ap_mode(pAdapter);
6530 if(status != VOS_STATUS_SUCCESS)
6531 {
6532 hddLog(VOS_TRACE_LEVEL_FATAL,
6533 "%s: Error initializing the ap mode", __func__);
6534 return -EINVAL;
6535 }
6536 hdd_set_conparam(1);
6537
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 /*interface type changed update in wiphy structure*/
6539 if(wdev)
6540 {
6541 wdev->iftype = type;
6542 pHddCtx->change_iface = type;
6543 }
6544 else
6545 {
6546 hddLog(VOS_TRACE_LEVEL_ERROR,
6547 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6548 return -EINVAL;
6549 }
6550 goto done;
6551 }
6552
6553 default:
6554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6555 __func__);
6556 return -EOPNOTSUPP;
6557 }
6558 }
6559 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 )
6562 {
6563 switch(type)
6564 {
6565 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306568#ifdef FEATURE_WLAN_TDLS
6569
6570 /* A Mutex Lock is introduced while changing the mode to
6571 * protect the concurrent access for the Adapters by TDLS
6572 * module.
6573 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306574 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306575#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306576 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006577 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006579 //Check for sub-string p2p to confirm its a p2p interface
6580 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006581 {
6582 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6583 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6584 }
6585 else
6586 {
6587 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 hdd_set_conparam(0);
6591 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6593 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306594#ifdef FEATURE_WLAN_TDLS
6595 mutex_unlock(&pHddCtx->tdls_lock);
6596#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306597 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 if( VOS_STATUS_SUCCESS != status )
6599 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006600 /* In case of JB, for P2P-GO, only change interface will be called,
6601 * This is the right place to enable back bmps_imps()
6602 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306603 if (pHddCtx->hdd_wlan_suspended)
6604 {
6605 hdd_set_pwrparams(pHddCtx);
6606 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006607 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 goto done;
6609 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6613 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 goto done;
6615 default:
6616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6617 __func__);
6618 return -EOPNOTSUPP;
6619
6620 }
6621
6622 }
6623 else
6624 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306625 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6626 __func__, hdd_device_modetoString(pAdapter->device_mode),
6627 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 return -EOPNOTSUPP;
6629 }
6630
6631
6632 if(pRoamProfile)
6633 {
6634 if ( LastBSSType != pRoamProfile->BSSType )
6635 {
6636 /*interface type changed update in wiphy structure*/
6637 wdev->iftype = type;
6638
6639 /*the BSS mode changed, We need to issue disconnect
6640 if connected or in IBSS disconnect state*/
6641 if ( hdd_connGetConnectedBssType(
6642 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6643 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6644 {
6645 /*need to issue a disconnect to CSR.*/
6646 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6647 if( eHAL_STATUS_SUCCESS ==
6648 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6649 pAdapter->sessionId,
6650 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6651 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306652 ret = wait_for_completion_interruptible_timeout(
6653 &pAdapter->disconnect_comp_var,
6654 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6655 if (ret <= 0)
6656 {
6657 hddLog(VOS_TRACE_LEVEL_ERROR,
6658 FL("wait on disconnect_comp_var failed %ld"), ret);
6659 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 }
6661 }
6662 }
6663 }
6664
6665done:
6666 /*set bitmask based on updated value*/
6667 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006668
6669 /* Only STA mode support TM now
6670 * all other mode, TM feature should be disabled */
6671 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6672 (~VOS_STA & pHddCtx->concurrency_mode) )
6673 {
6674 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6675 }
6676
Jeff Johnson295189b2012-06-20 16:38:30 -07006677#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306678 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07006679 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
6680 {
6681 //we are ok to do AMP
6682 pHddCtx->isAmpAllowed = VOS_TRUE;
6683 }
6684#endif //WLAN_BTAMP_FEATURE
6685 EXIT();
6686 return 0;
6687}
6688
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306689/*
6690 * FUNCTION: wlan_hdd_cfg80211_change_iface
6691 * wrapper function to protect the actual implementation from SSR.
6692 */
6693int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6694 struct net_device *ndev,
6695 enum nl80211_iftype type,
6696 u32 *flags,
6697 struct vif_params *params
6698 )
6699{
6700 int ret;
6701
6702 vos_ssr_protect(__func__);
6703 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6704 vos_ssr_unprotect(__func__);
6705
6706 return ret;
6707}
6708
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006709#ifdef FEATURE_WLAN_TDLS
6710static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6711 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6712{
6713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6715 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006716 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306718 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006719
6720 ENTER();
6721
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306722 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006723 {
6724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6725 "Invalid arguments");
6726 return -EINVAL;
6727 }
Hoonki Lee27511902013-03-14 18:19:06 -07006728
6729 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6730 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6731 {
6732 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6733 "%s: TDLS mode is disabled OR not enabled in FW."
6734 MAC_ADDRESS_STR " Request declined.",
6735 __func__, MAC_ADDR_ARRAY(mac));
6736 return -ENOTSUPP;
6737 }
6738
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006739 if (pHddCtx->isLogpInProgress)
6740 {
6741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6742 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006743 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006744 return -EBUSY;
6745 }
6746
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306747 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006748
6749 if ( NULL == pTdlsPeer ) {
6750 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6751 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6752 __func__, MAC_ADDR_ARRAY(mac), update);
6753 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006754 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006755
6756 /* in add station, we accept existing valid staId if there is */
6757 if ((0 == update) &&
6758 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6759 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006760 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006761 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006762 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006763 " link_status %d. staId %d. add station ignored.",
6764 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6765 return 0;
6766 }
6767 /* in change station, we accept only when staId is valid */
6768 if ((1 == update) &&
6769 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6770 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6771 {
6772 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6773 "%s: " MAC_ADDRESS_STR
6774 " link status %d. staId %d. change station %s.",
6775 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6776 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6777 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006778 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006779
6780 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306781 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006782 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6784 "%s: " MAC_ADDRESS_STR
6785 " TDLS setup is ongoing. Request declined.",
6786 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006787 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006788 }
6789
6790 /* first to check if we reached to maximum supported TDLS peer.
6791 TODO: for now, return -EPERM looks working fine,
6792 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306793 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6794 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006795 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6797 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306798 " TDLS Max peer already connected. Request declined."
6799 " Num of peers (%d), Max allowed (%d).",
6800 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6801 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006802 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006803 }
6804 else
6805 {
6806 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306807 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006808 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006809 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6811 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6812 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006813 return -EPERM;
6814 }
6815 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006816 if (0 == update)
6817 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006818
Jeff Johnsond75fe012013-04-06 10:53:06 -07006819 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306820 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006821 {
6822 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6823 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006824 if(StaParams->htcap_present)
6825 {
6826 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6827 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6828 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6829 "ht_capa->extended_capabilities: %0x",
6830 StaParams->HTCap.extendedHtCapInfo);
6831 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006832 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6833 "params->capability: %0x",StaParams->capability);
6834 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006835 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006836 if(StaParams->vhtcap_present)
6837 {
6838 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6839 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6840 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6841 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6842 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006843 {
6844 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006846 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6847 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6848 "[%d]: %x ", i, StaParams->supported_rates[i]);
6849 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006850 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306851 else if ((1 == update) && (NULL == StaParams))
6852 {
6853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6854 "%s : update is true, but staParams is NULL. Error!", __func__);
6855 return -EPERM;
6856 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006857
6858 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6859
6860 if (!update)
6861 {
6862 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6863 pAdapter->sessionId, mac);
6864 }
6865 else
6866 {
6867 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6868 pAdapter->sessionId, mac, StaParams);
6869 }
6870
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306871 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006872 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6873
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306874 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006875 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306877 "%s: timeout waiting for tdls add station indication %ld",
6878 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006879 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006880 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306881
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006882 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6883 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006885 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006886 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006887 }
6888
6889 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006890
6891error:
6892 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6893 return -EPERM;
6894
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006895}
6896#endif
6897
Jeff Johnson295189b2012-06-20 16:38:30 -07006898static int wlan_hdd_change_station(struct wiphy *wiphy,
6899 struct net_device *dev,
6900 u8 *mac,
6901 struct station_parameters *params)
6902{
6903 VOS_STATUS status = VOS_STATUS_SUCCESS;
6904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306905 hdd_context_t *pHddCtx;
6906 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006908#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006909 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006910 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306911 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006912#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006913 ENTER();
6914
Gopichand Nakkala29149562013-05-10 21:43:41 +05306915 if ((NULL == pAdapter))
6916 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306918 "invalid adapter ");
6919 return -EINVAL;
6920 }
6921
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306922 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6923 TRACE_CODE_HDD_CHANGE_STATION,
6924 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6926 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6927
6928 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6929 {
6930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6931 "invalid HDD state or HDD station context");
6932 return -EINVAL;
6933 }
6934
6935 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936 {
6937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6938 "%s:LOGP in Progress. Ignore!!!", __func__);
6939 return -EAGAIN;
6940 }
6941
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6943
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006944 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6945 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006947 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306949 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 WLANTL_STA_AUTHENTICATED);
6951
Gopichand Nakkala29149562013-05-10 21:43:41 +05306952 if (status != VOS_STATUS_SUCCESS)
6953 {
6954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6955 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6956 return -EINVAL;
6957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 }
6959 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006960 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6961 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306962#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006963 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6964 StaParams.capability = params->capability;
6965 StaParams.uapsd_queues = params->uapsd_queues;
6966 StaParams.max_sp = params->max_sp;
6967
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306968 /* Convert (first channel , number of channels) tuple to
6969 * the total list of channels. This goes with the assumption
6970 * that if the first channel is < 14, then the next channels
6971 * are an incremental of 1 else an incremental of 4 till the number
6972 * of channels.
6973 */
6974 if (0 != params->supported_channels_len) {
6975 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
6976 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
6977 {
6978 int wifi_chan_index;
6979 StaParams.supported_channels[j] = params->supported_channels[i];
6980 wifi_chan_index =
6981 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
6982 no_of_channels = params->supported_channels[i+1];
6983 for(k=1; k <= no_of_channels; k++)
6984 {
6985 StaParams.supported_channels[j+1] =
6986 StaParams.supported_channels[j] + wifi_chan_index;
6987 j+=1;
6988 }
6989 }
6990 StaParams.supported_channels_len = j;
6991 }
6992 vos_mem_copy(StaParams.supported_oper_classes,
6993 params->supported_oper_classes,
6994 params->supported_oper_classes_len);
6995 StaParams.supported_oper_classes_len =
6996 params->supported_oper_classes_len;
6997
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006998 if (0 != params->ext_capab_len)
6999 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7000 sizeof(StaParams.extn_capability));
7001
7002 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007003 {
7004 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007005 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007006 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007007
7008 StaParams.supported_rates_len = params->supported_rates_len;
7009
7010 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7011 * The supported_rates array , for all the structures propogating till Add Sta
7012 * to the firmware has to be modified , if the supplicant (ieee80211) is
7013 * modified to send more rates.
7014 */
7015
7016 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7017 */
7018 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7019 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7020
7021 if (0 != StaParams.supported_rates_len) {
7022 int i = 0;
7023 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7024 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007026 "Supported Rates with Length %d", StaParams.supported_rates_len);
7027 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007029 "[%d]: %0x", i, StaParams.supported_rates[i]);
7030 }
7031
7032 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007033 {
7034 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007035 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007036 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007037
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007038 if (0 != params->ext_capab_len ) {
7039 /*Define A Macro : TODO Sunil*/
7040 if ((1<<4) & StaParams.extn_capability[3]) {
7041 isBufSta = 1;
7042 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307043 /* TDLS Channel Switching Support */
7044 if ((1<<6) & StaParams.extn_capability[3]) {
7045 isOffChannelSupported = 1;
7046 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007047 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307048 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7049 &StaParams, isBufSta,
7050 isOffChannelSupported);
7051
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307052 if (VOS_STATUS_SUCCESS != status) {
7053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7054 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7055 return -EINVAL;
7056 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007057 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7058
7059 if (VOS_STATUS_SUCCESS != status) {
7060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7061 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7062 return -EINVAL;
7063 }
7064 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007065#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307066 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007067 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 return status;
7069}
7070
7071/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307072 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 * This function is used to initialize the key information
7074 */
7075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307076static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 struct net_device *ndev,
7078 u8 key_index, bool pairwise,
7079 const u8 *mac_addr,
7080 struct key_params *params
7081 )
7082#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307083static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 struct net_device *ndev,
7085 u8 key_index, const u8 *mac_addr,
7086 struct key_params *params
7087 )
7088#endif
7089{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 tCsrRoamSetKey setKey;
7092 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307093 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007094 v_U32_t roamId= 0xFF;
7095 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 hdd_hostapd_state_t *pHostapdState;
7097 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007098 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307099 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007100
7101 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307102
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307103 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7104 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7105 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7107 status = wlan_hdd_validate_context(pHddCtx);
7108
7109 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007110 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7112 "%s: HDD context is not valid", __func__);
7113 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007114 }
7115
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307116 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7117 __func__, hdd_device_modetoString(pAdapter->device_mode),
7118 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007119
7120 if (CSR_MAX_NUM_KEY <= key_index)
7121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007123 key_index);
7124
7125 return -EINVAL;
7126 }
7127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007128 if (CSR_MAX_KEY_LEN < params->key_len)
7129 {
7130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7131 params->key_len);
7132
7133 return -EINVAL;
7134 }
7135
7136 hddLog(VOS_TRACE_LEVEL_INFO,
7137 "%s: called with key index = %d & key length %d",
7138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007139
7140 /*extract key idx, key len and key*/
7141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7142 setKey.keyId = key_index;
7143 setKey.keyLength = params->key_len;
7144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 {
7148 case WLAN_CIPHER_SUITE_WEP40:
7149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7150 break;
7151
7152 case WLAN_CIPHER_SUITE_WEP104:
7153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7154 break;
7155
7156 case WLAN_CIPHER_SUITE_TKIP:
7157 {
7158 u8 *pKey = &setKey.Key[0];
7159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7160
7161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007164
7165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 |--------------|----------|----------|
7168 <---16bytes---><--8bytes--><--8bytes-->
7169
7170 */
7171 /*Sme expects the 32 bytes key to be in the below order
7172
7173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 |--------------|----------|----------|
7176 <---16bytes---><--8bytes--><--8bytes-->
7177 */
7178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007180
7181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007183
7184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007186
7187
7188 break;
7189 }
7190
7191 case WLAN_CIPHER_SUITE_CCMP:
7192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7193 break;
7194
7195#ifdef FEATURE_WLAN_WAPI
7196 case WLAN_CIPHER_SUITE_SMS4:
7197 {
7198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7200 params->key, params->key_len);
7201 return 0;
7202 }
7203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007204
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007205#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 case WLAN_CIPHER_SUITE_KRK:
7207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7208 break;
7209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007210
7211#ifdef WLAN_FEATURE_11W
7212 case WLAN_CIPHER_SUITE_AES_CMAC:
7213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007215#endif
7216
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 __func__, params->cipher);
7220 return -EOPNOTSUPP;
7221 }
7222
7223 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7224 __func__, setKey.encType);
7225
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007226 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7228 (!pairwise)
7229#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007230 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007231#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007232 )
7233 {
7234 /* set group key*/
7235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7236 "%s- %d: setting Broadcast key",
7237 __func__, __LINE__);
7238 setKey.keyDirection = eSIR_RX_ONLY;
7239 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7240 }
7241 else
7242 {
7243 /* set pairwise key*/
7244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7245 "%s- %d: setting pairwise key",
7246 __func__, __LINE__);
7247 setKey.keyDirection = eSIR_TX_RX;
7248 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7249 }
7250 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7251 {
7252 setKey.keyDirection = eSIR_TX_RX;
7253 /*Set the group key*/
7254 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7255 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007256
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007257 if ( 0 != status )
7258 {
7259 hddLog(VOS_TRACE_LEVEL_ERROR,
7260 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7261 return -EINVAL;
7262 }
7263 /*Save the keys here and call sme_RoamSetKey for setting
7264 the PTK after peer joins the IBSS network*/
7265 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7266 &setKey, sizeof(tCsrRoamSetKey));
7267 return status;
7268 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307269 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7270 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7271 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007273 if( pHostapdState->bssState == BSS_START )
7274 {
c_hpothu7c55da62014-01-23 18:34:02 +05307275 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7276 vos_status = wlan_hdd_check_ula_done(pAdapter);
7277
7278 if ( vos_status != VOS_STATUS_SUCCESS )
7279 {
7280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7281 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7282 __LINE__, vos_status );
7283
7284 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7285
7286 return -EINVAL;
7287 }
7288
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7290
7291 if ( status != eHAL_STATUS_SUCCESS )
7292 {
7293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7294 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7295 __LINE__, status );
7296 }
7297 }
7298
7299 /* Saving WEP keys */
7300 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7301 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7302 {
7303 //Save the wep key in ap context. Issue setkey after the BSS is started.
7304 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7305 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7306 }
7307 else
7308 {
7309 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007310 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007311 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7312 }
7313 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007314 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7315 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007316 {
7317 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7318 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7319
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7321 if (!pairwise)
7322#else
7323 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7324#endif
7325 {
7326 /* set group key*/
7327 if (pHddStaCtx->roam_info.deferKeyComplete)
7328 {
7329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7330 "%s- %d: Perform Set key Complete",
7331 __func__, __LINE__);
7332 hdd_PerformRoamSetKeyComplete(pAdapter);
7333 }
7334 }
7335
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7337
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007338 pWextState->roamProfile.Keys.defaultIndex = key_index;
7339
7340
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007341 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 params->key, params->key_len);
7343
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307344
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7346
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307347 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307349 __func__, setKey.peerMac[0], setKey.peerMac[1],
7350 setKey.peerMac[2], setKey.peerMac[3],
7351 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 setKey.keyDirection);
7353
7354 vos_status = wlan_hdd_check_ula_done(pAdapter);
7355
7356 if ( vos_status != VOS_STATUS_SUCCESS )
7357 {
7358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7359 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7360 __LINE__, vos_status );
7361
7362 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7363
7364 return -EINVAL;
7365
7366 }
7367
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007368#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307369 /* The supplicant may attempt to set the PTK once pre-authentication
7370 is done. Save the key in the UMAC and include it in the ADD BSS
7371 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007372 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307373 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007374 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307375 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7376 "%s: Update PreAuth Key success", __func__);
7377 return 0;
7378 }
7379 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7380 {
7381 hddLog(VOS_TRACE_LEVEL_ERROR,
7382 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307383 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007384 }
7385#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007386
7387 /* issue set key request to SME*/
7388 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7389 pAdapter->sessionId, &setKey, &roamId );
7390
7391 if ( 0 != status )
7392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307393 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7396 return -EINVAL;
7397 }
7398
7399
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307400 /* in case of IBSS as there was no information available about WEP keys during
7401 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007402 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307403 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7404 !( ( IW_AUTH_KEY_MGMT_802_1X
7405 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7407 )
7408 &&
7409 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7410 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7411 )
7412 )
7413 {
7414 setKey.keyDirection = eSIR_RX_ONLY;
7415 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7416
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307417 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307419 __func__, setKey.peerMac[0], setKey.peerMac[1],
7420 setKey.peerMac[2], setKey.peerMac[3],
7421 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 setKey.keyDirection);
7423
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007425 pAdapter->sessionId, &setKey, &roamId );
7426
7427 if ( 0 != status )
7428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307429 hddLog(VOS_TRACE_LEVEL_ERROR,
7430 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 __func__, status);
7432 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7433 return -EINVAL;
7434 }
7435 }
7436 }
7437
7438 return 0;
7439}
7440
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7442static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7443 struct net_device *ndev,
7444 u8 key_index, bool pairwise,
7445 const u8 *mac_addr,
7446 struct key_params *params
7447 )
7448#else
7449static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7450 struct net_device *ndev,
7451 u8 key_index, const u8 *mac_addr,
7452 struct key_params *params
7453 )
7454#endif
7455{
7456 int ret;
7457 vos_ssr_protect(__func__);
7458#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7459 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7460 mac_addr, params);
7461#else
7462 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7463 params);
7464#endif
7465 vos_ssr_unprotect(__func__);
7466
7467 return ret;
7468}
7469
Jeff Johnson295189b2012-06-20 16:38:30 -07007470/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307471 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 * This function is used to get the key information
7473 */
7474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307475static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307476 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307478 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 const u8 *mac_addr, void *cookie,
7480 void (*callback)(void *cookie, struct key_params*)
7481 )
7482#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307483static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 struct net_device *ndev,
7486 u8 key_index, const u8 *mac_addr, void *cookie,
7487 void (*callback)(void *cookie, struct key_params*)
7488 )
7489#endif
7490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307492 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7493 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 struct key_params params;
7495
7496 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307497
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7499 __func__, hdd_device_modetoString(pAdapter->device_mode),
7500 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307501
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 memset(&params, 0, sizeof(params));
7503
7504 if (CSR_MAX_NUM_KEY <= key_index)
7505 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007509
7510 switch(pRoamProfile->EncryptionType.encryptionType[0])
7511 {
7512 case eCSR_ENCRYPT_TYPE_NONE:
7513 params.cipher = IW_AUTH_CIPHER_NONE;
7514 break;
7515
7516 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7517 case eCSR_ENCRYPT_TYPE_WEP40:
7518 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7519 break;
7520
7521 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7522 case eCSR_ENCRYPT_TYPE_WEP104:
7523 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7524 break;
7525
7526 case eCSR_ENCRYPT_TYPE_TKIP:
7527 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7528 break;
7529
7530 case eCSR_ENCRYPT_TYPE_AES:
7531 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7532 break;
7533
7534 default:
7535 params.cipher = IW_AUTH_CIPHER_NONE;
7536 break;
7537 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307538
c_hpothuaaf19692014-05-17 17:01:48 +05307539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7540 TRACE_CODE_HDD_CFG80211_GET_KEY,
7541 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307542
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7544 params.seq_len = 0;
7545 params.seq = NULL;
7546 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7547 callback(cookie, &params);
7548 return 0;
7549}
7550
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7552static int wlan_hdd_cfg80211_get_key(
7553 struct wiphy *wiphy,
7554 struct net_device *ndev,
7555 u8 key_index, bool pairwise,
7556 const u8 *mac_addr, void *cookie,
7557 void (*callback)(void *cookie, struct key_params*)
7558 )
7559#else
7560static int wlan_hdd_cfg80211_get_key(
7561 struct wiphy *wiphy,
7562 struct net_device *ndev,
7563 u8 key_index, const u8 *mac_addr, void *cookie,
7564 void (*callback)(void *cookie, struct key_params*)
7565 )
7566#endif
7567{
7568 int ret;
7569
7570 vos_ssr_protect(__func__);
7571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7572 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7573 mac_addr, cookie, callback);
7574#else
7575 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7576 callback);
7577#endif
7578 vos_ssr_unprotect(__func__);
7579
7580 return ret;
7581}
7582
Jeff Johnson295189b2012-06-20 16:38:30 -07007583/*
7584 * FUNCTION: wlan_hdd_cfg80211_del_key
7585 * This function is used to delete the key information
7586 */
7587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307588static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307590 u8 key_index,
7591 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 const u8 *mac_addr
7593 )
7594#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307595static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 struct net_device *ndev,
7597 u8 key_index,
7598 const u8 *mac_addr
7599 )
7600#endif
7601{
7602 int status = 0;
7603
7604 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307605 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007606 //it is observed that this is invalidating peer
7607 //key index whenever re-key is done. This is affecting data link.
7608 //It should be ok to ignore del_key.
7609#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7611 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007612 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7613 tCsrRoamSetKey setKey;
7614 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307615
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 ENTER();
7617
7618 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7619 __func__,pAdapter->device_mode);
7620
7621 if (CSR_MAX_NUM_KEY <= key_index)
7622 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 key_index);
7625
7626 return -EINVAL;
7627 }
7628
7629 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7630 setKey.keyId = key_index;
7631
7632 if (mac_addr)
7633 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7634 else
7635 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7636
7637 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7638
7639 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307641 )
7642 {
7643
7644 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7646 if( pHostapdState->bssState == BSS_START)
7647 {
7648 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307649
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 if ( status != eHAL_STATUS_SUCCESS )
7651 {
7652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7653 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7654 __LINE__, status );
7655 }
7656 }
7657 }
7658 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307659 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 )
7661 {
7662 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7663
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307664 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7665
7666 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307668 __func__, setKey.peerMac[0], setKey.peerMac[1],
7669 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307671 if(pAdapter->sessionCtx.station.conn_info.connState ==
7672 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007675 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307676
Jeff Johnson295189b2012-06-20 16:38:30 -07007677 if ( 0 != status )
7678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307679 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007680 "%s: sme_RoamSetKey failure, returned %d",
7681 __func__, status);
7682 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7683 return -EINVAL;
7684 }
7685 }
7686 }
7687#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007688 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 return status;
7690}
7691
7692/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307693 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 * This function is used to set the default tx key index
7695 */
7696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307697static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 struct net_device *ndev,
7699 u8 key_index,
7700 bool unicast, bool multicast)
7701#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307702static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 struct net_device *ndev,
7704 u8 key_index)
7705#endif
7706{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307708 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307709 hdd_wext_state_t *pWextState;
7710 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307711 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007712
7713 ENTER();
7714
Gopichand Nakkala29149562013-05-10 21:43:41 +05307715 if ((NULL == pAdapter))
7716 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307718 "invalid adapter");
7719 return -EINVAL;
7720 }
7721
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307722 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7723 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7724 pAdapter->sessionId, key_index));
7725
Gopichand Nakkala29149562013-05-10 21:43:41 +05307726 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7727 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7728
7729 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7730 {
7731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7732 "invalid Wext state or HDD context");
7733 return -EINVAL;
7734 }
7735
Arif Hussain6d2a3322013-11-17 19:50:10 -08007736 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307738
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 if (CSR_MAX_NUM_KEY <= key_index)
7740 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 key_index);
7743
7744 return -EINVAL;
7745 }
7746
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7748 status = wlan_hdd_validate_context(pHddCtx);
7749
7750 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7753 "%s: HDD context is not valid", __func__);
7754 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007755 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307756
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307759 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307761 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007762 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007764 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307766 {
7767 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307769
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 tCsrRoamSetKey setKey;
7771 v_U32_t roamId= 0xFF;
7772 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307773
7774 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307776
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 Keys->defaultIndex = (u8)key_index;
7778 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7779 setKey.keyId = key_index;
7780 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781
7782 vos_mem_copy(&setKey.Key[0],
7783 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307785
Gopichand Nakkala29149562013-05-10 21:43:41 +05307786 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307787
7788 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 &pHddStaCtx->conn_info.bssId[0],
7790 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307791
Gopichand Nakkala29149562013-05-10 21:43:41 +05307792 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7793 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7794 eCSR_ENCRYPT_TYPE_WEP104)
7795 {
7796 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7797 even though ap is configured for WEP-40 encryption. In this canse the key length
7798 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7799 type(104) and switching encryption type to 40*/
7800 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7801 eCSR_ENCRYPT_TYPE_WEP40;
7802 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7803 eCSR_ENCRYPT_TYPE_WEP40;
7804 }
7805
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307806 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307808
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307810 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 if ( 0 != status )
7814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307815 hddLog(VOS_TRACE_LEVEL_ERROR,
7816 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 status);
7818 return -EINVAL;
7819 }
7820 }
7821 }
7822
7823 /* In SoftAp mode setting key direction for default mode */
7824 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7825 {
7826 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7827 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7828 (eCSR_ENCRYPT_TYPE_AES !=
7829 pWextState->roamProfile.EncryptionType.encryptionType[0])
7830 )
7831 {
7832 /* Saving key direction for default key index to TX default */
7833 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7834 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7835 }
7836 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307837
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 return status;
7839}
7840
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7842static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7843 struct net_device *ndev,
7844 u8 key_index,
7845 bool unicast, bool multicast)
7846#else
7847static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7848 struct net_device *ndev,
7849 u8 key_index)
7850#endif
7851{
7852 int ret;
7853 vos_ssr_protect(__func__);
7854#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7855 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7856 multicast);
7857#else
7858 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7859#endif
7860 vos_ssr_unprotect(__func__);
7861
7862 return ret;
7863}
7864
Jeff Johnson295189b2012-06-20 16:38:30 -07007865/*
7866 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7867 * This function is used to inform the BSS details to nl80211 interface.
7868 */
7869static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7870 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7871{
7872 struct net_device *dev = pAdapter->dev;
7873 struct wireless_dev *wdev = dev->ieee80211_ptr;
7874 struct wiphy *wiphy = wdev->wiphy;
7875 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7876 int chan_no;
7877 int ie_length;
7878 const char *ie;
7879 unsigned int freq;
7880 struct ieee80211_channel *chan;
7881 int rssi = 0;
7882 struct cfg80211_bss *bss = NULL;
7883
7884 ENTER();
7885
7886 if( NULL == pBssDesc )
7887 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007888 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 return bss;
7890 }
7891
7892 chan_no = pBssDesc->channelId;
7893 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7894 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7895
7896 if( NULL == ie )
7897 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007898 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 return bss;
7900 }
7901
7902#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7903 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7904 {
7905 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7906 }
7907 else
7908 {
7909 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7910 }
7911#else
7912 freq = ieee80211_channel_to_frequency(chan_no);
7913#endif
7914
7915 chan = __ieee80211_get_channel(wiphy, freq);
7916
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307917 if (!chan) {
7918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7919 return NULL;
7920 }
7921
Abhishek Singhaee43942014-06-16 18:55:47 +05307922 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007923
Abhishek Singhaee43942014-06-16 18:55:47 +05307924 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307925 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 pBssDesc->capabilityInfo,
7927 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307928 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007929}
7930
7931
7932
7933/*
7934 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7935 * This function is used to inform the BSS details to nl80211 interface.
7936 */
7937struct cfg80211_bss*
7938wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7939 tSirBssDescription *bss_desc
7940 )
7941{
7942 /*
7943 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7944 already exists in bss data base of cfg80211 for that particular BSS ID.
7945 Using cfg80211_inform_bss_frame to update the bss entry instead of
7946 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7947 now there is no possibility to get the mgmt(probe response) frame from PE,
7948 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7949 cfg80211_inform_bss_frame.
7950 */
7951 struct net_device *dev = pAdapter->dev;
7952 struct wireless_dev *wdev = dev->ieee80211_ptr;
7953 struct wiphy *wiphy = wdev->wiphy;
7954 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007955#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7956 qcom_ie_age *qie_age = NULL;
7957 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7958#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007960#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 const char *ie =
7962 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7963 unsigned int freq;
7964 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307965 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 struct cfg80211_bss *bss_status = NULL;
7967 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7968 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007969 hdd_context_t *pHddCtx;
7970 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007971#ifdef WLAN_OPEN_SOURCE
7972 struct timespec ts;
7973#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007974
Wilson Yangf80a0542013-10-07 13:02:37 -07007975 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7976 status = wlan_hdd_validate_context(pHddCtx);
7977
7978 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05307979 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07007980 {
7981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7982 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
7983 return NULL;
7984 }
7985
7986
7987 if (0 != status)
7988 {
7989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7990 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07007991 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07007992 }
7993
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307994 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07007995 if (!mgmt)
7996 {
7997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7998 "%s: memory allocation failed ", __func__);
7999 return NULL;
8000 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008001
Jeff Johnson295189b2012-06-20 16:38:30 -07008002 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008003
8004#ifdef WLAN_OPEN_SOURCE
8005 /* Android does not want the timestamp from the frame.
8006 Instead it wants a monotonic increasing value */
8007 get_monotonic_boottime(&ts);
8008 mgmt->u.probe_resp.timestamp =
8009 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8010#else
8011 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8013 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008014
8015#endif
8016
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8018 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008019
8020#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8021 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8022 /* Assuming this is the last IE, copy at the end */
8023 ie_length -=sizeof(qcom_ie_age);
8024 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8025 qie_age->element_id = QCOM_VENDOR_IE_ID;
8026 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8027 qie_age->oui_1 = QCOM_OUI1;
8028 qie_age->oui_2 = QCOM_OUI2;
8029 qie_age->oui_3 = QCOM_OUI3;
8030 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8031 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8032#endif
8033
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308035 if (bss_desc->fProbeRsp)
8036 {
8037 mgmt->frame_control |=
8038 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8039 }
8040 else
8041 {
8042 mgmt->frame_control |=
8043 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008045
8046#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308047 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8049 {
8050 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8051 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308052 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8054
8055 {
8056 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8057 }
8058 else
8059 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8061 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 kfree(mgmt);
8063 return NULL;
8064 }
8065#else
8066 freq = ieee80211_channel_to_frequency(chan_no);
8067#endif
8068 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008069 /*when the band is changed on the fly using the GUI, three things are done
8070 * 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)
8071 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8072 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8073 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8074 * and discards the channels correponding to previous band and calls back with zero bss results.
8075 * 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
8076 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8077 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8078 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8079 * So drop the bss and continue to next bss.
8080 */
8081 if(chan == NULL)
8082 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008084 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008085 return NULL;
8086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308088 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 * */
8090 if (( eConnectionState_Associated ==
8091 pAdapter->sessionCtx.station.conn_info.connState ) &&
8092 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8093 pAdapter->sessionCtx.station.conn_info.bssId,
8094 WNI_CFG_BSSID_LEN)))
8095 {
8096 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8097 rssi = (pAdapter->rssi * 100);
8098 }
8099 else
8100 {
8101 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8102 }
8103
Nirav Shah20ac06f2013-12-12 18:14:06 +05308104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8105 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8106 chan->center_freq, (int)(rssi/100));
8107
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8109 frame_len, rssi, GFP_KERNEL);
8110 kfree(mgmt);
8111 return bss_status;
8112}
8113
8114/*
8115 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8116 * This function is used to update the BSS data base of CFG8011
8117 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308118struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 tCsrRoamInfo *pRoamInfo
8120 )
8121{
8122 tCsrRoamConnectedProfile roamProfile;
8123 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8124 struct cfg80211_bss *bss = NULL;
8125
8126 ENTER();
8127
8128 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8129 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8130
8131 if (NULL != roamProfile.pBssDesc)
8132 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 &roamProfile);
8135
8136 if (NULL == bss)
8137 {
8138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8139 __func__);
8140 }
8141
8142 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8143 }
8144 else
8145 {
8146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8147 __func__);
8148 }
8149 return bss;
8150}
8151
8152/*
8153 * FUNCTION: wlan_hdd_cfg80211_update_bss
8154 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308155static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8156 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008157 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308158{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308159 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 tCsrScanResultInfo *pScanResult;
8161 eHalStatus status = 0;
8162 tScanResultHandle pResult;
8163 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008164 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008165
8166 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308167
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8169 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8170 NO_SESSION, pAdapter->sessionId));
8171
Wilson Yangf80a0542013-10-07 13:02:37 -07008172 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8173
8174 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8177 "%s:LOGP in Progress. Ignore!!!",__func__);
8178 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 }
8180
Wilson Yangf80a0542013-10-07 13:02:37 -07008181
8182 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308183 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008184 {
8185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8186 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8187 return VOS_STATUS_E_PERM;
8188 }
8189
8190
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 /*
8192 * start getting scan results and populate cgf80211 BSS database
8193 */
8194 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8195
8196 /* no scan results */
8197 if (NULL == pResult)
8198 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308199 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8200 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 return status;
8202 }
8203
8204 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8205
8206 while (pScanResult)
8207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308208 /*
8209 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8210 * entry already exists in bss data base of cfg80211 for that
8211 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8212 * bss entry instead of cfg80211_inform_bss, But this call expects
8213 * mgmt packet as input. As of now there is no possibility to get
8214 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 * ieee80211_mgmt(probe response) and passing to c
8216 * fg80211_inform_bss_frame.
8217 * */
8218
8219 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8220 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308221
Jeff Johnson295189b2012-06-20 16:38:30 -07008222
8223 if (NULL == bss_status)
8224 {
8225 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008226 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 }
8228 else
8229 {
Yue Maf49ba872013-08-19 12:04:25 -07008230 cfg80211_put_bss(
8231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8232 wiphy,
8233#endif
8234 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 }
8236
8237 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8238 }
8239
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308240 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008241
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308242 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008243}
8244
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008245void
8246hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8247{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308248 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008249 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008250} /****** end hddPrintMacAddr() ******/
8251
8252void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008253hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008254{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308255 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008256 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008257 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8258 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8259 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008260} /****** end hddPrintPmkId() ******/
8261
8262//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8263//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8264
8265//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8266//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8267
8268#define dump_bssid(bssid) \
8269 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008270 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8271 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008272 }
8273
8274#define dump_pmkid(pMac, pmkid) \
8275 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008276 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8277 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008278 }
8279
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008280#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008281/*
8282 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8283 * This function is used to notify the supplicant of a new PMKSA candidate.
8284 */
8285int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308286 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008287 int index, bool preauth )
8288{
Jeff Johnsone7245742012-09-05 17:12:55 -07008289#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008290 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008291 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008292
8293 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008294 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008295
8296 if( NULL == pRoamInfo )
8297 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008298 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008299 return -EINVAL;
8300 }
8301
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008302 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8303 {
8304 dump_bssid(pRoamInfo->bssid);
8305 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008306 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008307 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008308#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308309 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008310}
8311#endif //FEATURE_WLAN_LFR
8312
Yue Maef608272013-04-08 23:09:17 -07008313#ifdef FEATURE_WLAN_LFR_METRICS
8314/*
8315 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8316 * 802.11r/LFR metrics reporting function to report preauth initiation
8317 *
8318 */
8319#define MAX_LFR_METRICS_EVENT_LENGTH 100
8320VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8321 tCsrRoamInfo *pRoamInfo)
8322{
8323 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8324 union iwreq_data wrqu;
8325
8326 ENTER();
8327
8328 if (NULL == pAdapter)
8329 {
8330 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8331 return VOS_STATUS_E_FAILURE;
8332 }
8333
8334 /* create the event */
8335 memset(&wrqu, 0, sizeof(wrqu));
8336 memset(metrics_notification, 0, sizeof(metrics_notification));
8337
8338 wrqu.data.pointer = metrics_notification;
8339 wrqu.data.length = scnprintf(metrics_notification,
8340 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8341 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8342
8343 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8344
8345 EXIT();
8346
8347 return VOS_STATUS_SUCCESS;
8348}
8349
8350/*
8351 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8352 * 802.11r/LFR metrics reporting function to report preauth completion
8353 * or failure
8354 */
8355VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8356 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8357{
8358 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8359 union iwreq_data wrqu;
8360
8361 ENTER();
8362
8363 if (NULL == pAdapter)
8364 {
8365 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8366 return VOS_STATUS_E_FAILURE;
8367 }
8368
8369 /* create the event */
8370 memset(&wrqu, 0, sizeof(wrqu));
8371 memset(metrics_notification, 0, sizeof(metrics_notification));
8372
8373 scnprintf(metrics_notification, sizeof(metrics_notification),
8374 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8375 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8376
8377 if (1 == preauth_status)
8378 strncat(metrics_notification, " TRUE", 5);
8379 else
8380 strncat(metrics_notification, " FALSE", 6);
8381
8382 wrqu.data.pointer = metrics_notification;
8383 wrqu.data.length = strlen(metrics_notification);
8384
8385 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8386
8387 EXIT();
8388
8389 return VOS_STATUS_SUCCESS;
8390}
8391
8392/*
8393 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8394 * 802.11r/LFR metrics reporting function to report handover initiation
8395 *
8396 */
8397VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8398 tCsrRoamInfo *pRoamInfo)
8399{
8400 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8401 union iwreq_data wrqu;
8402
8403 ENTER();
8404
8405 if (NULL == pAdapter)
8406 {
8407 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8408 return VOS_STATUS_E_FAILURE;
8409 }
8410
8411 /* create the event */
8412 memset(&wrqu, 0, sizeof(wrqu));
8413 memset(metrics_notification, 0, sizeof(metrics_notification));
8414
8415 wrqu.data.pointer = metrics_notification;
8416 wrqu.data.length = scnprintf(metrics_notification,
8417 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8418 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8419
8420 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8421
8422 EXIT();
8423
8424 return VOS_STATUS_SUCCESS;
8425}
8426#endif
8427
Jeff Johnson295189b2012-06-20 16:38:30 -07008428/*
8429 * FUNCTION: hdd_cfg80211_scan_done_callback
8430 * scanning callback function, called after finishing scan
8431 *
8432 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308433static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8435{
8436 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308437 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008439 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8440 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 struct cfg80211_scan_request *req = NULL;
8442 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308443 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308444 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008445
8446 ENTER();
8447
8448 hddLog(VOS_TRACE_LEVEL_INFO,
8449 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008450 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 __func__, halHandle, pContext, (int) scanId, (int) status);
8452
Kiet Lamac06e2c2013-10-23 16:25:07 +05308453 pScanInfo->mScanPendingCounter = 0;
8454
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308456 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 &pScanInfo->scan_req_completion_event,
8458 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308459 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308461 hddLog(VOS_TRACE_LEVEL_ERROR,
8462 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008464 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 }
8466
Yue Maef608272013-04-08 23:09:17 -07008467 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 {
8469 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008470 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 }
8472
8473 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308474 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 {
8476 hddLog(VOS_TRACE_LEVEL_INFO,
8477 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008478 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 (int) scanId);
8480 }
8481
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308482 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 pAdapter);
8484
8485 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008487
8488
8489 /* If any client wait scan result through WEXT
8490 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008491 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 {
8493 /* The other scan request waiting for current scan finish
8494 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008495 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008497 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 }
8499 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008500 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 {
8502 struct net_device *dev = pAdapter->dev;
8503 union iwreq_data wrqu;
8504 int we_event;
8505 char *msg;
8506
8507 memset(&wrqu, '\0', sizeof(wrqu));
8508 we_event = SIOCGIWSCAN;
8509 msg = NULL;
8510 wireless_send_event(dev, we_event, &wrqu, msg);
8511 }
8512 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008513 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008514
8515 /* Get the Scan Req */
8516 req = pAdapter->request;
8517
8518 if (!req)
8519 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008520 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008521 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008522 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 }
8524
8525 /*
8526 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308527 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 req->n_ssids = 0;
8529 req->n_channels = 0;
8530 req->ie = 0;
8531
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008533 /* Scan is no longer pending */
8534 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008535
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008536 /*
8537 * cfg80211_scan_done informing NL80211 about completion
8538 * of scanning
8539 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308540 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8541 {
8542 aborted = true;
8543 }
8544 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008545 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008546
Jeff Johnsone7245742012-09-05 17:12:55 -07008547allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008548 /* release the wake lock at the end of the scan*/
8549 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008550
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008551 /* Acquire wakelock to handle the case where APP's tries to suspend
8552 * immediatly after the driver gets connect request(i.e after scan)
8553 * from supplicant, this result in app's is suspending and not able
8554 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308555 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008556
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008557#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308558 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8559 {
8560 wlan_hdd_tdls_scan_done_callback(pAdapter);
8561 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008562#endif
8563
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 EXIT();
8565 return 0;
8566}
8567
8568/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308569 * FUNCTION: hdd_isConnectionInProgress
8570 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008571 *
8572 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308573v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008574{
8575 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8576 hdd_station_ctx_t *pHddStaCtx = NULL;
8577 hdd_adapter_t *pAdapter = NULL;
8578 VOS_STATUS status = 0;
8579 v_U8_t staId = 0;
8580 v_U8_t *staMac = NULL;
8581
c_hpothu9b781ba2013-12-30 20:57:45 +05308582 if (TRUE == pHddCtx->btCoexModeSet)
8583 {
8584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308585 FL("BTCoex Mode operation in progress"));
8586 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308587 }
8588
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008589 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8590
8591 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8592 {
8593 pAdapter = pAdapterNode->pAdapter;
8594
8595 if( pAdapter )
8596 {
8597 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308598 "%s: Adapter with device mode %s (%d) exists",
8599 __func__, hdd_device_modetoString(pAdapter->device_mode),
8600 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308601 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8602 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8603 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8604 (eConnectionState_Connecting ==
8605 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8606 {
8607 hddLog(VOS_TRACE_LEVEL_ERROR,
8608 "%s: %p(%d) Connection is in progress", __func__,
8609 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8610 return VOS_TRUE;
8611 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008612 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308613 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8614 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008615 {
8616 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8617 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308618 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008619 {
8620 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8621 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008622 "%s: client " MAC_ADDRESS_STR
8623 " is in the middle of WPS/EAPOL exchange.", __func__,
8624 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308625 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008626 }
8627 }
8628 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8629 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8630 {
8631 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308633 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008634 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8635 {
8636 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8637
8638 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008639 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8640 "middle of WPS/EAPOL exchange.", __func__,
8641 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308642 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008643 }
8644 }
8645 }
8646 }
8647 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8648 pAdapterNode = pNext;
8649 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308650 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308651}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008652
8653/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308654 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 * this scan respond to scan trigger and update cfg80211 scan database
8656 * later, scan dump command can be used to recieve scan results
8657 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308658int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008659#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8660 struct net_device *dev,
8661#endif
8662 struct cfg80211_scan_request *request)
8663{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308664 hdd_adapter_t *pAdapter = NULL;
8665 hdd_context_t *pHddCtx = NULL;
8666 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308667 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008668 tCsrScanRequest scanRequest;
8669 tANI_U8 *channelList = NULL, i;
8670 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308671 int status;
8672 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008674
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8676 struct net_device *dev = NULL;
8677 if (NULL == request)
8678 {
8679 hddLog(VOS_TRACE_LEVEL_ERROR,
8680 "%s: scan req param null", __func__);
8681 return -EINVAL;
8682 }
8683 dev = request->wdev->netdev;
8684#endif
8685
8686 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8687 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8688 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8689
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 ENTER();
8691
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308692
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8694 __func__, hdd_device_modetoString(pAdapter->device_mode),
8695 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308696
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308697 status = wlan_hdd_validate_context(pHddCtx);
8698
8699 if (0 != status)
8700 {
8701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8702 "%s: HDD context is not valid", __func__);
8703 return status;
8704 }
8705
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308706 if (NULL == pwextBuf)
8707 {
8708 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8709 __func__);
8710 return -EIO;
8711 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308712 cfg_param = pHddCtx->cfg_ini;
8713 pScanInfo = &pHddCtx->scan_info;
8714
Jeff Johnson295189b2012-06-20 16:38:30 -07008715#ifdef WLAN_BTAMP_FEATURE
8716 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008717 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008719 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 "%s: No scanning when AMP is on", __func__);
8721 return -EOPNOTSUPP;
8722 }
8723#endif
8724 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008725 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008727 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308728 "%s: Not scanning on device_mode = %s (%d)",
8729 __func__, hdd_device_modetoString(pAdapter->device_mode),
8730 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 return -EOPNOTSUPP;
8732 }
8733
8734 if (TRUE == pScanInfo->mScanPending)
8735 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308736 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8737 {
8738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8739 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008740 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 }
8742
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308743 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008744 //Channel and action frame is pending
8745 //Otherwise Cancel Remain On Channel and allow Scan
8746 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008747 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008748 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008750 return -EBUSY;
8751 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008752#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008753 /* if tdls disagree scan right now, return immediately.
8754 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8755 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8756 */
8757 status = wlan_hdd_tdls_scan_callback (pAdapter,
8758 wiphy,
8759#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8760 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008761#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008762 request);
8763 if(status <= 0)
8764 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308765 if(!status)
8766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8767 "scan rejected %d", __func__, status);
8768 else
8769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8770 __func__, status);
8771
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008772 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008773 }
8774#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008775
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8777 {
8778 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008779 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8783 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308784 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 "%s: MAX TM Level Scan not allowed", __func__);
8786 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308787 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008788 }
8789 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8790
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008791 /* Check if scan is allowed at this point of time.
8792 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308793 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008794 {
8795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8796 return -EBUSY;
8797 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308798
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8800
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308801 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8802 (int)request->n_ssids);
8803
8804 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8805 * Becasue of this, driver is assuming that this is not wildcard scan and so
8806 * is not aging out the scan results.
8807 */
8808 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308810 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308812
8813 if ((request->ssids) && (0 < request->n_ssids))
8814 {
8815 tCsrSSIDInfo *SsidInfo;
8816 int j;
8817 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8818 /* Allocate num_ssid tCsrSSIDInfo structure */
8819 SsidInfo = scanRequest.SSIDs.SSIDList =
8820 ( tCsrSSIDInfo *)vos_mem_malloc(
8821 request->n_ssids*sizeof(tCsrSSIDInfo));
8822
8823 if(NULL == scanRequest.SSIDs.SSIDList)
8824 {
8825 hddLog(VOS_TRACE_LEVEL_ERROR,
8826 "%s: memory alloc failed SSIDInfo buffer", __func__);
8827 return -ENOMEM;
8828 }
8829
8830 /* copy all the ssid's and their length */
8831 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8832 {
8833 /* get the ssid length */
8834 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8835 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8836 SsidInfo->SSID.length);
8837 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8838 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8839 j, SsidInfo->SSID.ssId);
8840 }
8841 /* set the scan type to active */
8842 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8843 }
8844 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8847 TRACE_CODE_HDD_CFG80211_SCAN,
8848 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 /* set the scan type to active */
8850 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308852 else
8853 {
8854 /*Set the scan type to default type, in this case it is ACTIVE*/
8855 scanRequest.scanType = pScanInfo->scan_mode;
8856 }
8857 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8858 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008859
8860 /* set BSSType to default type */
8861 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8862
8863 /*TODO: scan the requested channels only*/
8864
8865 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308866 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308868 hddLog(VOS_TRACE_LEVEL_WARN,
8869 "No of Scan Channels exceeded limit: %d", request->n_channels);
8870 request->n_channels = MAX_CHANNEL;
8871 }
8872
8873 hddLog(VOS_TRACE_LEVEL_INFO,
8874 "No of Scan Channels: %d", request->n_channels);
8875
8876
8877 if( request->n_channels )
8878 {
8879 char chList [(request->n_channels*5)+1];
8880 int len;
8881 channelList = vos_mem_malloc( request->n_channels );
8882 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308883 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308884 hddLog(VOS_TRACE_LEVEL_ERROR,
8885 "%s: memory alloc failed channelList", __func__);
8886 status = -ENOMEM;
8887 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308888 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308889
8890 for( i = 0, len = 0; i < request->n_channels ; i++ )
8891 {
8892 channelList[i] = request->channels[i]->hw_value;
8893 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8894 }
8895
Nirav Shah20ac06f2013-12-12 18:14:06 +05308896 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308897 "Channel-List: %s ", chList);
8898 }
c_hpothu53512302014-04-15 18:49:53 +05308899
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308900 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8901 scanRequest.ChannelInfo.ChannelList = channelList;
8902
8903 /* set requestType to full scan */
8904 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8905
8906 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8907 * search (Flush on both full scan and social scan but not on single
8908 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8909 */
8910
8911 /* Supplicant does single channel scan after 8-way handshake
8912 * and in that case driver shoudnt flush scan results. If
8913 * driver flushes the scan results here and unfortunately if
8914 * the AP doesnt respond to our probe req then association
8915 * fails which is not desired
8916 */
8917
8918 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8919 {
8920 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8921 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8922 pAdapter->sessionId );
8923 }
8924
8925 if( request->ie_len )
8926 {
8927 /* save this for future association (join requires this) */
8928 /*TODO: Array needs to be converted to dynamic allocation,
8929 * as multiple ie.s can be sent in cfg80211_scan_request structure
8930 * CR 597966
8931 */
8932 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8933 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8934 pScanInfo->scanAddIE.length = request->ie_len;
8935
8936 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8937 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8938 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308940 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308942 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8943 memcpy( pwextBuf->roamProfile.addIEScan,
8944 request->ie, request->ie_len);
8945 }
8946 else
8947 {
8948 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8949 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 }
8951
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308952 }
8953 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8954 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8955
8956 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8957 request->ie_len);
8958 if (pP2pIe != NULL)
8959 {
8960#ifdef WLAN_FEATURE_P2P_DEBUG
8961 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8962 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8963 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308964 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308965 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8966 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8967 "Go nego completed to Connection is started");
8968 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8969 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308970 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308971 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8972 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308974 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8975 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8976 "Disconnected state to Connection is started");
8977 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8978 "for 4way Handshake");
8979 }
8980#endif
8981
8982 /* no_cck will be set during p2p find to disable 11b rates */
8983 if(TRUE == request->no_cck)
8984 {
8985 hddLog(VOS_TRACE_LEVEL_INFO,
8986 "%s: This is a P2P Search", __func__);
8987 scanRequest.p2pSearch = 1;
8988
8989 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05308990 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308991 /* set requestType to P2P Discovery */
8992 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
8993 }
8994
8995 /*
8996 Skip Dfs Channel in case of P2P Search
8997 if it is set in ini file
8998 */
8999 if(cfg_param->skipDfsChnlInP2pSearch)
9000 {
9001 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309002 }
9003 else
9004 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309005 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009007
Agarwal Ashish4f616132013-12-30 23:32:50 +05309008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 }
9010 }
9011
9012 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9013
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009014 /* acquire the wakelock to avoid the apps suspend during the scan. To
9015 * address the following issues.
9016 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9017 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9018 * for long time, this result in apps running at full power for long time.
9019 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9020 * be stuck in full power because of resume BMPS
9021 */
9022 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009023
Nirav Shah20ac06f2013-12-12 18:14:06 +05309024 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9025 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309026 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9027 scanRequest.requestType, scanRequest.scanType,
9028 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309029 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9030
Jeff Johnsone7245742012-09-05 17:12:55 -07009031 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 pAdapter->sessionId, &scanRequest, &scanId,
9033 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009034
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 if (eHAL_STATUS_SUCCESS != status)
9036 {
9037 hddLog(VOS_TRACE_LEVEL_ERROR,
9038 "%s: sme_ScanRequest returned error %d", __func__, status);
9039 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009040 if(eHAL_STATUS_RESOURCES == status)
9041 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9043 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009044 status = -EBUSY;
9045 } else {
9046 status = -EIO;
9047 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009048 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 goto free_mem;
9050 }
9051
9052 pScanInfo->mScanPending = TRUE;
9053 pAdapter->request = request;
9054 pScanInfo->scanId = scanId;
9055
9056 complete(&pScanInfo->scan_req_completion_event);
9057
9058free_mem:
9059 if( scanRequest.SSIDs.SSIDList )
9060 {
9061 vos_mem_free(scanRequest.SSIDs.SSIDList);
9062 }
9063
9064 if( channelList )
9065 vos_mem_free( channelList );
9066
9067 EXIT();
9068
9069 return status;
9070}
9071
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309072int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9074 struct net_device *dev,
9075#endif
9076 struct cfg80211_scan_request *request)
9077{
9078 int ret;
9079
9080 vos_ssr_protect(__func__);
9081 ret = __wlan_hdd_cfg80211_scan(wiphy,
9082#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9083 dev,
9084#endif
9085 request);
9086 vos_ssr_unprotect(__func__);
9087
9088 return ret;
9089}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009090
9091void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9092{
9093 v_U8_t iniDot11Mode =
9094 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9095 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9096
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309097 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9098 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009099 switch ( iniDot11Mode )
9100 {
9101 case eHDD_DOT11_MODE_AUTO:
9102 case eHDD_DOT11_MODE_11ac:
9103 case eHDD_DOT11_MODE_11ac_ONLY:
9104#ifdef WLAN_FEATURE_11AC
9105 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9106#else
9107 hddDot11Mode = eHDD_DOT11_MODE_11n;
9108#endif
9109 break;
9110 case eHDD_DOT11_MODE_11n:
9111 case eHDD_DOT11_MODE_11n_ONLY:
9112 hddDot11Mode = eHDD_DOT11_MODE_11n;
9113 break;
9114 default:
9115 hddDot11Mode = iniDot11Mode;
9116 break;
9117 }
9118 /* This call decides required channel bonding mode */
9119 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9120 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9121 operationChannel);
9122}
9123
Jeff Johnson295189b2012-06-20 16:38:30 -07009124/*
9125 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309126 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009127 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309128int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009129 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009130{
9131 int status = 0;
9132 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009133 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009134 v_U32_t roamId;
9135 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 eCsrAuthType RSNAuthType;
9137
9138 ENTER();
9139
9140 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9142
9143 status = wlan_hdd_validate_context(pHddCtx);
9144 if (status)
9145 {
9146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9147 "%s: HDD context is not valid!", __func__);
9148 return status;
9149 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309150
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9152 {
9153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9154 return -EINVAL;
9155 }
9156
9157 pRoamProfile = &pWextState->roamProfile;
9158
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309159 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009161 hdd_station_ctx_t *pHddStaCtx;
9162 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009163
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309164 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9166 {
9167 /*QoS not enabled in cfg file*/
9168 pRoamProfile->uapsd_mask = 0;
9169 }
9170 else
9171 {
9172 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309173 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9175 }
9176
9177 pRoamProfile->SSIDs.numOfSSIDs = 1;
9178 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9179 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309180 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009181 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9182 ssid, ssid_len);
9183
9184 if (bssid)
9185 {
9186 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9187 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9188 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309189 /* Save BSSID in seperate variable as well, as RoamProfile
9190 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009191 case of join failure we should send valid BSSID to supplicant
9192 */
9193 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9194 WNI_CFG_BSSID_LEN);
9195 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009196 else
9197 {
9198 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009200
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309201 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9202 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9204 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309205 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 /*set gen ie*/
9207 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9208 /*set auth*/
9209 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9210 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009211#ifdef FEATURE_WLAN_WAPI
9212 if (pAdapter->wapi_info.nWapiMode)
9213 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009214 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 switch (pAdapter->wapi_info.wapiAuthMode)
9216 {
9217 case WAPI_AUTH_MODE_PSK:
9218 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009219 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 pAdapter->wapi_info.wapiAuthMode);
9221 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9222 break;
9223 }
9224 case WAPI_AUTH_MODE_CERT:
9225 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009226 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 pAdapter->wapi_info.wapiAuthMode);
9228 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9229 break;
9230 }
9231 } // End of switch
9232 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9233 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9234 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009235 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 pRoamProfile->AuthType.numEntries = 1;
9237 pRoamProfile->EncryptionType.numEntries = 1;
9238 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9239 pRoamProfile->mcEncryptionType.numEntries = 1;
9240 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9241 }
9242 }
9243#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309244#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309245 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309246 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9247 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9248 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309249 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9250 sizeof (tSirGtkOffloadParams));
9251 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309252 }
9253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 pRoamProfile->csrPersona = pAdapter->device_mode;
9255
Jeff Johnson32d95a32012-09-10 13:15:23 -07009256 if( operatingChannel )
9257 {
9258 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9259 pRoamProfile->ChannelInfo.numOfChannels = 1;
9260 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009261 else
9262 {
9263 pRoamProfile->ChannelInfo.ChannelList = NULL;
9264 pRoamProfile->ChannelInfo.numOfChannels = 0;
9265 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009266 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9267 {
9268 hdd_select_cbmode(pAdapter,operatingChannel);
9269 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309270
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009271 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9272 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309273 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009274 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009275 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9276 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309277 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9278 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309279 {
9280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9281 "%s: Set HDD connState to eConnectionState_Connecting",
9282 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009283 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9284 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309285 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309286 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 pAdapter->sessionId, pRoamProfile, &roamId);
9288
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309289 if ((eHAL_STATUS_SUCCESS != status) &&
9290 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9291 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309292
9293 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9295 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9296 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309297 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009298 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309299 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009300
9301 pRoamProfile->ChannelInfo.ChannelList = NULL;
9302 pRoamProfile->ChannelInfo.numOfChannels = 0;
9303
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 }
9305 else
9306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9308 return -EINVAL;
9309 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009310 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 return status;
9312}
9313
9314/*
9315 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9316 * This function is used to set the authentication type (OPEN/SHARED).
9317 *
9318 */
9319static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9320 enum nl80211_auth_type auth_type)
9321{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309322 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9324
9325 ENTER();
9326
9327 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309328 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309331 hddLog(VOS_TRACE_LEVEL_INFO,
9332 "%s: set authentication type to AUTOSWITCH", __func__);
9333 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9334 break;
9335
9336 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009337#ifdef WLAN_FEATURE_VOWIFI_11R
9338 case NL80211_AUTHTYPE_FT:
9339#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309340 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 "%s: set authentication type to OPEN", __func__);
9342 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9343 break;
9344
9345 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309346 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 "%s: set authentication type to SHARED", __func__);
9348 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9349 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009350#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 "%s: set authentication type to CCKM WPA", __func__);
9354 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9355 break;
9356#endif
9357
9358
9359 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309360 hddLog(VOS_TRACE_LEVEL_ERROR,
9361 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 auth_type);
9363 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9364 return -EINVAL;
9365 }
9366
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 pHddStaCtx->conn_info.authType;
9369 return 0;
9370}
9371
9372/*
9373 * FUNCTION: wlan_hdd_set_akm_suite
9374 * This function is used to set the key mgmt type(PSK/8021x).
9375 *
9376 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309377static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 u32 key_mgmt
9379 )
9380{
9381 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9382 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309383
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 /*set key mgmt type*/
9385 switch(key_mgmt)
9386 {
9387 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309388#ifdef WLAN_FEATURE_VOWIFI_11R
9389 case WLAN_AKM_SUITE_FT_PSK:
9390#endif
9391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 __func__);
9393 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9394 break;
9395
9396 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309397#ifdef WLAN_FEATURE_VOWIFI_11R
9398 case WLAN_AKM_SUITE_FT_8021X:
9399#endif
9400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 __func__);
9402 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9403 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009404#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009405#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9406#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9407 case WLAN_AKM_SUITE_CCKM:
9408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9409 __func__);
9410 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9411 break;
9412#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009413#ifndef WLAN_AKM_SUITE_OSEN
9414#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9415 case WLAN_AKM_SUITE_OSEN:
9416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9417 __func__);
9418 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9419 break;
9420#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
9422 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 __func__, key_mgmt);
9425 return -EINVAL;
9426
9427 }
9428 return 0;
9429}
9430
9431/*
9432 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309433 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 * (NONE/WEP40/WEP104/TKIP/CCMP).
9435 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309436static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9437 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009438 bool ucast
9439 )
9440{
9441 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309442 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9444
9445 ENTER();
9446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 __func__, cipher);
9451 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9452 }
9453 else
9454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309455
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 {
9459 case IW_AUTH_CIPHER_NONE:
9460 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9461 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309464 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309468 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309470
Jeff Johnson295189b2012-06-20 16:38:30 -07009471 case WLAN_CIPHER_SUITE_TKIP:
9472 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9473 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309474
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 case WLAN_CIPHER_SUITE_CCMP:
9476 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9477 break;
9478#ifdef FEATURE_WLAN_WAPI
9479 case WLAN_CIPHER_SUITE_SMS4:
9480 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9481 break;
9482#endif
9483
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009484#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 case WLAN_CIPHER_SUITE_KRK:
9486 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9487 break;
9488#endif
9489 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 __func__, cipher);
9492 return -EOPNOTSUPP;
9493 }
9494 }
9495
9496 if (ucast)
9497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 __func__, encryptionType);
9500 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9501 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309502 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 encryptionType;
9504 }
9505 else
9506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 __func__, encryptionType);
9509 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9510 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9511 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9512 }
9513
9514 return 0;
9515}
9516
9517
9518/*
9519 * FUNCTION: wlan_hdd_cfg80211_set_ie
9520 * This function is used to parse WPA/RSN IE's.
9521 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309522int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9523 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 size_t ie_len
9525 )
9526{
9527 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9528 u8 *genie = ie;
9529 v_U16_t remLen = ie_len;
9530#ifdef FEATURE_WLAN_WAPI
9531 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9532 u16 *tmp;
9533 v_U16_t akmsuiteCount;
9534 int *akmlist;
9535#endif
9536 ENTER();
9537
9538 /* clear previous assocAddIE */
9539 pWextState->assocAddIE.length = 0;
9540 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009541 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
9543 while (remLen >= 2)
9544 {
9545 v_U16_t eLen = 0;
9546 v_U8_t elementId;
9547 elementId = *genie++;
9548 eLen = *genie++;
9549 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550
Arif Hussain6d2a3322013-11-17 19:50:10 -08009551 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309553
9554 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309556 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009557 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 -07009558 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309559 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 "%s: Invalid WPA IE", __func__);
9561 return -EINVAL;
9562 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309563 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 {
9565 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309566 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9570 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009571 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9572 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 VOS_ASSERT(0);
9574 return -ENOMEM;
9575 }
9576 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9577 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9578 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309579
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9581 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9582 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9583 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309584 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9585 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9587 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9588 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9589 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9590 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9591 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309593 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 {
9595 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309596 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309598
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9600 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009601 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9602 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 VOS_ASSERT(0);
9604 return -ENOMEM;
9605 }
9606 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9607 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9608 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309609
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9611 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009613#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309614 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9615 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 /*Consider WFD IE, only for P2P Client */
9617 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9618 {
9619 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309620 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309622
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9624 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009625 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9626 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 VOS_ASSERT(0);
9628 return -ENOMEM;
9629 }
9630 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9631 // WPS IE + P2P IE + WFD IE
9632 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9633 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9636 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9637 }
9638#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009639 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309640 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009641 HS20_OUI_TYPE_SIZE)) )
9642 {
9643 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309644 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009645 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009646
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009647 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9648 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009649 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9650 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009651 VOS_ASSERT(0);
9652 return -ENOMEM;
9653 }
9654 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9655 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009656
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009657 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9658 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9659 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009660 /* Appending OSEN Information Element in Assiciation Request */
9661 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9662 OSEN_OUI_TYPE_SIZE)) )
9663 {
9664 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9665 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9666 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009667
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009668 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9669 {
9670 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9671 "Need bigger buffer space");
9672 VOS_ASSERT(0);
9673 return -ENOMEM;
9674 }
9675 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9676 pWextState->assocAddIE.length += eLen + 2;
9677
9678 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9679 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9680 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9681 }
9682
9683 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009684 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9685
9686 /* populating as ADDIE in beacon frames */
9687 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9688 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9689 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9690 {
9691 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9692 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9693 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9694 {
9695 hddLog(LOGE,
9696 "Coldn't pass "
9697 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9698 }
9699 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9700 else
9701 hddLog(LOGE,
9702 "Could not pass on "
9703 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9704
9705 /* IBSS mode doesn't contain params->proberesp_ies still
9706 beaconIE's need to be populated in probe response frames */
9707 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9708 {
9709 u16 rem_probe_resp_ie_len = eLen + 2;
9710 u8 probe_rsp_ie_len[3] = {0};
9711 u8 counter = 0;
9712
9713 /* Check Probe Resp Length if it is greater then 255 then
9714 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9715 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9716 not able Store More then 255 bytes into One Variable */
9717
9718 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9719 {
9720 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9721 {
9722 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9723 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9724 }
9725 else
9726 {
9727 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9728 rem_probe_resp_ie_len = 0;
9729 }
9730 }
9731
9732 rem_probe_resp_ie_len = 0;
9733
9734 if (probe_rsp_ie_len[0] > 0)
9735 {
9736 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9737 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9738 (tANI_U8*)(genie - 2),
9739 probe_rsp_ie_len[0], NULL,
9740 eANI_BOOLEAN_FALSE)
9741 == eHAL_STATUS_FAILURE)
9742 {
9743 hddLog(LOGE,
9744 "Could not pass"
9745 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9746 }
9747 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9748 }
9749
9750 if (probe_rsp_ie_len[1] > 0)
9751 {
9752 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9753 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9754 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9755 probe_rsp_ie_len[1], NULL,
9756 eANI_BOOLEAN_FALSE)
9757 == eHAL_STATUS_FAILURE)
9758 {
9759 hddLog(LOGE,
9760 "Could not pass"
9761 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9762 }
9763 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9764 }
9765
9766 if (probe_rsp_ie_len[2] > 0)
9767 {
9768 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9769 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9770 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9771 probe_rsp_ie_len[2], NULL,
9772 eANI_BOOLEAN_FALSE)
9773 == eHAL_STATUS_FAILURE)
9774 {
9775 hddLog(LOGE,
9776 "Could not pass"
9777 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9778 }
9779 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9780 }
9781
9782 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9783 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9784 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9785 {
9786 hddLog(LOGE,
9787 "Could not pass"
9788 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9789 }
9790 }
9791 else
9792 {
9793 // Reset WNI_CFG_PROBE_RSP Flags
9794 wlan_hdd_reset_prob_rspies(pAdapter);
9795
9796 hddLog(VOS_TRACE_LEVEL_INFO,
9797 "%s: No Probe Response IE received in set beacon",
9798 __func__);
9799 }
9800 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 break;
9802 case DOT11F_EID_RSN:
9803 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9804 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9805 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9806 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9807 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9808 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009809 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9810 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309811 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009812 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309813 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009814 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309815
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009816 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9817 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009818 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9819 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009820 VOS_ASSERT(0);
9821 return -ENOMEM;
9822 }
9823 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9824 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309825
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009826 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9827 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9828 break;
9829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009830#ifdef FEATURE_WLAN_WAPI
9831 case WLAN_EID_WAPI:
9832 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009833 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 pAdapter->wapi_info.nWapiMode);
9835 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309836 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 akmsuiteCount = WPA_GET_LE16(tmp);
9838 tmp = tmp + 1;
9839 akmlist = (int *)(tmp);
9840 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9841 {
9842 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9843 }
9844 else
9845 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009846 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 VOS_ASSERT(0);
9848 return -EINVAL;
9849 }
9850
9851 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9852 {
9853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009854 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309856 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309858 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009860 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9862 }
9863 break;
9864#endif
9865 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309866 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009868 /* when Unknown IE is received we should break and continue
9869 * to the next IE in the buffer instead we were returning
9870 * so changing this to break */
9871 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 }
9873 genie += eLen;
9874 remLen -= eLen;
9875 }
9876 EXIT();
9877 return 0;
9878}
9879
9880/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309881 * FUNCTION: hdd_isWPAIEPresent
9882 * Parse the received IE to find the WPA IE
9883 *
9884 */
9885static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9886{
9887 v_U8_t eLen = 0;
9888 v_U16_t remLen = ie_len;
9889 v_U8_t elementId = 0;
9890
9891 while (remLen >= 2)
9892 {
9893 elementId = *ie++;
9894 eLen = *ie++;
9895 remLen -= 2;
9896 if (eLen > remLen)
9897 {
9898 hddLog(VOS_TRACE_LEVEL_ERROR,
9899 "%s: IE length is wrong %d", __func__, eLen);
9900 return FALSE;
9901 }
9902 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9903 {
9904 /* OUI - 0x00 0X50 0XF2
9905 WPA Information Element - 0x01
9906 WPA version - 0x01*/
9907 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9908 return TRUE;
9909 }
9910 ie += eLen;
9911 remLen -= eLen;
9912 }
9913 return FALSE;
9914}
9915
9916/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309918 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 * parameters during connect operation.
9920 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 struct cfg80211_connect_params *req
9923 )
9924{
9925 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 ENTER();
9928
9929 /*set wpa version*/
9930 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9931
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309932 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309934 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 {
9936 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9937 }
9938 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9939 {
9940 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9941 }
9942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309943
9944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 pWextState->wpaVersion);
9946
9947 /*set authentication type*/
9948 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9949
9950 if (0 > status)
9951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309952 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 "%s: failed to set authentication type ", __func__);
9954 return status;
9955 }
9956
9957 /*set key mgmt type*/
9958 if (req->crypto.n_akm_suites)
9959 {
9960 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9961 if (0 > status)
9962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 __func__);
9965 return status;
9966 }
9967 }
9968
9969 /*set pairwise cipher type*/
9970 if (req->crypto.n_ciphers_pairwise)
9971 {
9972 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9973 req->crypto.ciphers_pairwise[0], true);
9974 if (0 > status)
9975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309976 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 "%s: failed to set unicast cipher type", __func__);
9978 return status;
9979 }
9980 }
9981 else
9982 {
9983 /*Reset previous cipher suite to none*/
9984 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
9985 if (0 > status)
9986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 "%s: failed to set unicast cipher type", __func__);
9989 return status;
9990 }
9991 }
9992
9993 /*set group cipher type*/
9994 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
9995 false);
9996
9997 if (0 > status)
9998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 __func__);
10001 return status;
10002 }
10003
Chet Lanctot186b5732013-03-18 10:26:30 -070010004#ifdef WLAN_FEATURE_11W
10005 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10006#endif
10007
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10009 if (req->ie_len)
10010 {
10011 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10012 if ( 0 > status)
10013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 __func__);
10016 return status;
10017 }
10018 }
10019
10020 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010021 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 {
10023 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10024 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10025 )
10026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10029 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 __func__);
10032 return -EOPNOTSUPP;
10033 }
10034 else
10035 {
10036 u8 key_len = req->key_len;
10037 u8 key_idx = req->key_idx;
10038
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010039 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 && (CSR_MAX_NUM_KEY > key_idx)
10041 )
10042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 hddLog(VOS_TRACE_LEVEL_INFO,
10044 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 __func__, key_idx, key_len);
10046 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010049 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 (u8)key_len;
10051 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10052 }
10053 }
10054 }
10055 }
10056
10057 return status;
10058}
10059
10060/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010061 * FUNCTION: wlan_hdd_try_disconnect
10062 * This function is used to disconnect from previous
10063 * connection
10064 */
10065static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10066{
10067 long ret = 0;
10068 hdd_station_ctx_t *pHddStaCtx;
10069 eMib_dot11DesiredBssType connectedBssType;
10070
10071 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10072
10073 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10074
10075 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10076 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10077 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10078 {
10079 /* Issue disconnect to CSR */
10080 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10081 if( eHAL_STATUS_SUCCESS ==
10082 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10083 pAdapter->sessionId,
10084 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10085 {
10086 ret = wait_for_completion_interruptible_timeout(
10087 &pAdapter->disconnect_comp_var,
10088 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10089 if (0 >= ret)
10090 {
10091 hddLog(LOGE, FL("Failed to receive disconnect event"));
10092 return -EALREADY;
10093 }
10094 }
10095 }
10096 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10097 {
10098 ret = wait_for_completion_interruptible_timeout(
10099 &pAdapter->disconnect_comp_var,
10100 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10101 if (0 >= ret)
10102 {
10103 hddLog(LOGE, FL("Failed to receive disconnect event"));
10104 return -EALREADY;
10105 }
10106 }
10107
10108 return 0;
10109}
10110
10111/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010112 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010113 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 * parameters during connect operation.
10115 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010116static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 struct net_device *ndev,
10118 struct cfg80211_connect_params *req
10119 )
10120{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010121 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010122 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010124 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010125
10126 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010127
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10129 TRACE_CODE_HDD_CFG80211_CONNECT,
10130 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010131 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010132 "%s: device_mode = %s (%d)", __func__,
10133 hdd_device_modetoString(pAdapter->device_mode),
10134 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010135
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010136 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010137 if (!pHddCtx)
10138 {
10139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10140 "%s: HDD context is null", __func__);
10141 return VOS_STATUS_E_FAILURE;
10142 }
10143
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010144 status = wlan_hdd_validate_context(pHddCtx);
10145
10146 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10149 "%s: HDD context is not valid", __func__);
10150 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 }
10152
10153#ifdef WLAN_BTAMP_FEATURE
10154 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010157 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010159 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 }
10161#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010162
10163 //If Device Mode is Station Concurrent Sessions Exit BMps
10164 //P2P Mode will be taken care in Open/close adapter
10165 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
10166 (vos_concurrent_sessions_running()))
10167 {
10168 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10169 }
10170
10171 /*Try disconnecting if already in connected state*/
10172 status = wlan_hdd_try_disconnect(pAdapter);
10173 if ( 0 > status)
10174 {
10175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10176 " connection"));
10177 return -EALREADY;
10178 }
10179
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010181 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010182
10183 if ( 0 > status)
10184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 __func__);
10187 return status;
10188 }
10189
Mohit Khanna765234a2012-09-11 15:08:35 -070010190 if ( req->channel )
10191 {
10192 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10193 req->ssid_len, req->bssid,
10194 req->channel->hw_value);
10195 }
10196 else
10197 {
10198 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010199 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010200 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010201
10202 if (0 > status)
10203 {
10204 //ReEnable BMPS if disabled
10205 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10206 (NULL != pHddCtx))
10207 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010208 if (pHddCtx->hdd_wlan_suspended)
10209 {
10210 hdd_set_pwrparams(pHddCtx);
10211 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 //ReEnable Bmps and Imps back
10213 hdd_enable_bmps_imps(pHddCtx);
10214 }
10215
10216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10217 return status;
10218 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010219 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 EXIT();
10221 return status;
10222}
10223
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010224static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10225 struct net_device *ndev,
10226 struct cfg80211_connect_params *req)
10227{
10228 int ret;
10229 vos_ssr_protect(__func__);
10230 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10231 vos_ssr_unprotect(__func__);
10232
10233 return ret;
10234}
Jeff Johnson295189b2012-06-20 16:38:30 -070010235
10236/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010237 * FUNCTION: wlan_hdd_disconnect
10238 * This function is used to issue a disconnect request to SME
10239 */
10240int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10241{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010242 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010243 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010244 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010245 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010246
10247 status = wlan_hdd_validate_context(pHddCtx);
10248
10249 if (0 != status)
10250 {
10251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10252 "%s: HDD context is not valid", __func__);
10253 return status;
10254 }
10255
10256 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10258 "%s: Set HDD connState to eConnectionState_Disconnecting",
10259 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010260 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010261 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010262
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010263 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010264
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010265 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10266 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010267 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10268 {
10269 hddLog(VOS_TRACE_LEVEL_INFO,
10270 FL("status = %d, already disconnected"),
10271 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010272
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010273 }
10274 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010275 {
10276 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010277 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010278 __func__, (int)status );
10279 return -EINVAL;
10280 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010281 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010282 &pAdapter->disconnect_comp_var,
10283 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010284 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010285 {
10286 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010287 "%s: Failed to disconnect, timed out", __func__);
10288 return -ETIMEDOUT;
10289 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010290 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010291 {
10292 hddLog(VOS_TRACE_LEVEL_ERROR,
10293 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010294 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010295 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10297 FL("Set HDD connState to eConnectionState_NotConnected"));
10298 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10299
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010300 /*stop tx queues*/
10301 netif_tx_disable(pAdapter->dev);
10302 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010303 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010304}
10305
10306
10307/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010308 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 * This function is used to issue a disconnect request to SME
10310 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010311static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 struct net_device *dev,
10313 u16 reason
10314 )
10315{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010317 tCsrRoamProfile *pRoamProfile =
10318 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010319 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010320 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10321 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010322#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010323 tANI_U8 staIdx;
10324#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10329 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10330 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10332 __func__, hdd_device_modetoString(pAdapter->device_mode),
10333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010334
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10336 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010338 status = wlan_hdd_validate_context(pHddCtx);
10339
10340 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010341 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10343 "%s: HDD context is not valid", __func__);
10344 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010346
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 if (NULL != pRoamProfile)
10348 {
10349 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010350 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10351 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010353 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010355 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 switch(reason)
10357 {
10358 case WLAN_REASON_MIC_FAILURE:
10359 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10360 break;
10361
10362 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10363 case WLAN_REASON_DISASSOC_AP_BUSY:
10364 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10365 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10366 break;
10367
10368 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10369 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010370 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10372 break;
10373
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 default:
10375 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10376 break;
10377 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010378 pScanInfo = &pHddCtx->scan_info;
10379 if (pScanInfo->mScanPending)
10380 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010381 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010382 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010383 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10384 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010386
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010387#ifdef FEATURE_WLAN_TDLS
10388 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010389 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010390 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010391 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10392 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010393 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010394 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010395 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010396 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010397 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010398 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010399 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010400 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010401 pAdapter->sessionId,
10402 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010403 }
10404 }
10405#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010406 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010407 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10408 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 {
10410 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010411 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 __func__, (int)status );
10413 return -EINVAL;
10414 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010416 else
10417 {
10418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10419 "called while in %d state", __func__,
10420 pHddStaCtx->conn_info.connState);
10421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 }
10423 else
10424 {
10425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10426 }
10427
10428 return status;
10429}
10430
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010431static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10432 struct net_device *dev,
10433 u16 reason
10434 )
10435{
10436 int ret;
10437 vos_ssr_protect(__func__);
10438 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10439 vos_ssr_unprotect(__func__);
10440
10441 return ret;
10442}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010443
Jeff Johnson295189b2012-06-20 16:38:30 -070010444/*
10445 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 * settings in IBSS mode.
10448 */
10449static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010450 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 struct cfg80211_ibss_params *params
10452 )
10453{
10454 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 ENTER();
10460
10461 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010462 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010463
10464 if (params->ie_len && ( NULL != params->ie) )
10465 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010466 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10467 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 {
10469 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10470 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10471 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010472 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010474 tDot11fIEWPA dot11WPAIE;
10475 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010476 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010477
Wilson Yang00256342013-10-10 23:13:38 -070010478 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010479 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10480 params->ie_len, DOT11F_EID_WPA);
10481 if ( NULL != ie )
10482 {
10483 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10484 // Unpack the WPA IE
10485 //Skip past the EID byte and length byte - and four byte WiFi OUI
10486 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10487 &ie[2+4],
10488 ie[1] - 4,
10489 &dot11WPAIE);
10490 /*Extract the multicast cipher, the encType for unicast
10491 cipher for wpa-none is none*/
10492 encryptionType =
10493 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010495 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010496
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10498
10499 if (0 > status)
10500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 __func__);
10503 return status;
10504 }
10505 }
10506
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010507 pWextState->roamProfile.AuthType.authType[0] =
10508 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10510
10511 if (params->privacy)
10512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010513 /* Security enabled IBSS, At this time there is no information available
10514 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010516 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010518 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 *enable privacy bit in beacons */
10520
10521 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10522 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010523 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10524 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10526 pWextState->roamProfile.EncryptionType.numEntries = 1;
10527 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 return status;
10529}
10530
10531/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010532 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010533 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010535static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 struct net_device *dev,
10537 struct cfg80211_ibss_params *params
10538 )
10539{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010540 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10542 tCsrRoamProfile *pRoamProfile;
10543 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010544 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10546 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010547
10548 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010549
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010550 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10551 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10552 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010553 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010554 "%s: device_mode = %s (%d)", __func__,
10555 hdd_device_modetoString(pAdapter->device_mode),
10556 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010557
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010558 status = wlan_hdd_validate_context(pHddCtx);
10559
10560 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10563 "%s: HDD context is not valid", __func__);
10564 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010565 }
10566
10567 if (NULL == pWextState)
10568 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010569 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 __func__);
10571 return -EIO;
10572 }
10573
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010574 /*Try disconnecting if already in connected state*/
10575 status = wlan_hdd_try_disconnect(pAdapter);
10576 if ( 0 > status)
10577 {
10578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10579 " IBSS connection"));
10580 return -EALREADY;
10581 }
10582
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 pRoamProfile = &pWextState->roamProfile;
10584
10585 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010587 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010588 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 return -EINVAL;
10590 }
10591
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010592 /* BSSID is provided by upper layers hence no need to AUTO generate */
10593 if (NULL != params->bssid) {
10594 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10595 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10596 hddLog (VOS_TRACE_LEVEL_ERROR,
10597 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10598 return -EIO;
10599 }
10600 }
krunal sonie9002db2013-11-25 14:24:17 -080010601 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10602 {
10603 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10604 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10605 {
10606 hddLog (VOS_TRACE_LEVEL_ERROR,
10607 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10608 return -EIO;
10609 }
10610 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10611 if (!params->bssid)
10612 {
10613 hddLog (VOS_TRACE_LEVEL_ERROR,
10614 "%s:Failed memory allocation", __func__);
10615 return -EIO;
10616 }
10617 vos_mem_copy((v_U8_t *)params->bssid,
10618 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10619 VOS_MAC_ADDR_SIZE);
10620 alloc_bssid = VOS_TRUE;
10621 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010622
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010624 if (NULL !=
10625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10626 params->chandef.chan)
10627#else
10628 params->channel)
10629#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 {
10631 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010632 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10633 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10634 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10635 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010636
10637 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010639 ieee80211_frequency_to_channel(
10640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10641 params->chandef.chan->center_freq);
10642#else
10643 params->channel->center_freq);
10644#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010645
10646 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10647 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10650 __func__);
10651 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010653
10654 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010656 if (channelNum == validChan[indx])
10657 {
10658 break;
10659 }
10660 }
10661 if (indx >= numChans)
10662 {
10663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 __func__, channelNum);
10665 return -EINVAL;
10666 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010667 /* Set the Operational Channel */
10668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10669 channelNum);
10670 pRoamProfile->ChannelInfo.numOfChannels = 1;
10671 pHddStaCtx->conn_info.operationChannel = channelNum;
10672 pRoamProfile->ChannelInfo.ChannelList =
10673 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 }
10675
10676 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010677 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 if (status < 0)
10679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 __func__);
10682 return status;
10683 }
10684
10685 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010686 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010687 params->ssid_len, params->bssid,
10688 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010689
10690 if (0 > status)
10691 {
10692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10693 return status;
10694 }
10695
krunal sonie9002db2013-11-25 14:24:17 -080010696 if (NULL != params->bssid &&
10697 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10698 alloc_bssid == VOS_TRUE)
10699 {
10700 vos_mem_free(params->bssid);
10701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 return 0;
10703}
10704
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010705static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10706 struct net_device *dev,
10707 struct cfg80211_ibss_params *params
10708 )
10709{
10710 int ret = 0;
10711
10712 vos_ssr_protect(__func__);
10713 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10714 vos_ssr_unprotect(__func__);
10715
10716 return ret;
10717}
10718
Jeff Johnson295189b2012-06-20 16:38:30 -070010719/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010720 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010721 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010723static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 struct net_device *dev
10725 )
10726{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010728 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10729 tCsrRoamProfile *pRoamProfile;
10730 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010731 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010732
10733 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010734
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10736 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10737 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010738 status = wlan_hdd_validate_context(pHddCtx);
10739
10740 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10743 "%s: HDD context is not valid", __func__);
10744 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010745 }
10746
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010747 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10748 hdd_device_modetoString(pAdapter->device_mode),
10749 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 if (NULL == pWextState)
10751 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010752 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 __func__);
10754 return -EIO;
10755 }
10756
10757 pRoamProfile = &pWextState->roamProfile;
10758
10759 /* Issue disconnect only if interface type is set to IBSS */
10760 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010762 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 __func__);
10764 return -EINVAL;
10765 }
10766
10767 /* Issue Disconnect request */
10768 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10769 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10770 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10771
10772 return 0;
10773}
10774
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010775static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10776 struct net_device *dev
10777 )
10778{
10779 int ret = 0;
10780
10781 vos_ssr_protect(__func__);
10782 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10783 vos_ssr_unprotect(__func__);
10784
10785 return ret;
10786}
10787
Jeff Johnson295189b2012-06-20 16:38:30 -070010788/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010789 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 * This function is used to set the phy parameters
10791 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10792 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010793static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010794 u32 changed)
10795{
10796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10797 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010798 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010799
10800 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10802 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10803 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010804 status = wlan_hdd_validate_context(pHddCtx);
10805
10806 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10809 "%s: HDD context is not valid", __func__);
10810 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010811 }
10812
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10814 {
10815 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10816 WNI_CFG_RTS_THRESHOLD_STAMAX :
10817 wiphy->rts_threshold;
10818
10819 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010820 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010822 hddLog(VOS_TRACE_LEVEL_ERROR,
10823 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 __func__, rts_threshold);
10825 return -EINVAL;
10826 }
10827
10828 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10829 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010830 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010832 hddLog(VOS_TRACE_LEVEL_ERROR,
10833 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 __func__, rts_threshold);
10835 return -EIO;
10836 }
10837
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010838 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010839 rts_threshold);
10840 }
10841
10842 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10843 {
10844 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10845 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10846 wiphy->frag_threshold;
10847
10848 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010849 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010851 hddLog(VOS_TRACE_LEVEL_ERROR,
10852 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 frag_threshold);
10854 return -EINVAL;
10855 }
10856
10857 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10858 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010859 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010861 hddLog(VOS_TRACE_LEVEL_ERROR,
10862 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 __func__, frag_threshold);
10864 return -EIO;
10865 }
10866
10867 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10868 frag_threshold);
10869 }
10870
10871 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10872 || (changed & WIPHY_PARAM_RETRY_LONG))
10873 {
10874 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10875 wiphy->retry_short :
10876 wiphy->retry_long;
10877
10878 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10879 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 __func__, retry_value);
10883 return -EINVAL;
10884 }
10885
10886 if (changed & WIPHY_PARAM_RETRY_SHORT)
10887 {
10888 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10889 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010890 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010892 hddLog(VOS_TRACE_LEVEL_ERROR,
10893 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 __func__, retry_value);
10895 return -EIO;
10896 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010897 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 __func__, retry_value);
10899 }
10900 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10901 {
10902 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10903 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010904 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010906 hddLog(VOS_TRACE_LEVEL_ERROR,
10907 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 __func__, retry_value);
10909 return -EIO;
10910 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010911 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 __func__, retry_value);
10913 }
10914 }
10915
10916 return 0;
10917}
10918
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010919static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10920 u32 changed)
10921{
10922 int ret;
10923
10924 vos_ssr_protect(__func__);
10925 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10926 vos_ssr_unprotect(__func__);
10927
10928 return ret;
10929}
10930
Jeff Johnson295189b2012-06-20 16:38:30 -070010931/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010932 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 * This function is used to set the txpower
10934 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010935static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010936#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10937 struct wireless_dev *wdev,
10938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010939#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010941#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010943#endif
10944 int dbm)
10945{
10946 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010947 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010948 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10949 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010950 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010951
10952 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010953 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10954 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
10955 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010956 status = wlan_hdd_validate_context(pHddCtx);
10957
10958 if (0 != status)
10959 {
10960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10961 "%s: HDD context is not valid", __func__);
10962 return status;
10963 }
10964
10965 hHal = pHddCtx->hHal;
10966
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010967 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
10968 dbm, ccmCfgSetCallback,
10969 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010971 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
10973 return -EIO;
10974 }
10975
10976 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
10977 dbm);
10978
10979 switch(type)
10980 {
10981 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
10982 /* Fall through */
10983 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
10984 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
10985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
10987 __func__);
10988 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 }
10990 break;
10991 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 __func__);
10994 return -EOPNOTSUPP;
10995 break;
10996 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
10998 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 return -EIO;
11000 }
11001
11002 return 0;
11003}
11004
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011005static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11006#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11007 struct wireless_dev *wdev,
11008#endif
11009#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11010 enum tx_power_setting type,
11011#else
11012 enum nl80211_tx_power_setting type,
11013#endif
11014 int dbm)
11015{
11016 int ret;
11017 vos_ssr_protect(__func__);
11018 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11019#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11020 wdev,
11021#endif
11022#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11023 type,
11024#else
11025 type,
11026#endif
11027 dbm);
11028 vos_ssr_unprotect(__func__);
11029
11030 return ret;
11031}
11032
Jeff Johnson295189b2012-06-20 16:38:30 -070011033/*
11034 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11035 * This function is used to read the txpower
11036 */
Yue Maf49ba872013-08-19 12:04:25 -070011037static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11038#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11039 struct wireless_dev *wdev,
11040#endif
11041 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011042{
11043
11044 hdd_adapter_t *pAdapter;
11045 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011046 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011047
Jeff Johnsone7245742012-09-05 17:12:55 -070011048 ENTER();
11049
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011050 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011051
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011052 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11055 "%s: HDD context is not valid", __func__);
11056 *dbm = 0;
11057 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011058 }
11059
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11061 if (NULL == pAdapter)
11062 {
11063 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11064 return -ENOENT;
11065 }
11066
11067 wlan_hdd_get_classAstats(pAdapter);
11068 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11069
Jeff Johnsone7245742012-09-05 17:12:55 -070011070 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 return 0;
11072}
11073
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011074static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 u8* mac, struct station_info *sinfo)
11076{
11077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11078 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11079 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011080 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011081
11082 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11083 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011084
11085 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11086 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11087 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11088 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11089 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11090 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11091 tANI_U16 maxRate = 0;
11092 tANI_U16 myRate;
11093 tANI_U16 currentRate = 0;
11094 tANI_U8 maxSpeedMCS = 0;
11095 tANI_U8 maxMCSIdx = 0;
11096 tANI_U8 rateFlag = 1;
11097 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011098 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011100
Leo Chang6f8870f2013-03-26 18:11:36 -070011101#ifdef WLAN_FEATURE_11AC
11102 tANI_U32 vht_mcs_map;
11103 eDataRate11ACMaxMcs vhtMaxMcs;
11104#endif /* WLAN_FEATURE_11AC */
11105
Jeff Johnsone7245742012-09-05 17:12:55 -070011106 ENTER();
11107
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11109 (0 == ssidlen))
11110 {
11111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11112 " Invalid ssidlen, %d", __func__, ssidlen);
11113 /*To keep GUI happy*/
11114 return 0;
11115 }
11116
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011117 status = wlan_hdd_validate_context(pHddCtx);
11118
11119 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011120 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11122 "%s: HDD context is not valid", __func__);
11123 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011124 }
11125
Jeff Johnson295189b2012-06-20 16:38:30 -070011126
Kiet Lam3b17fc82013-09-27 05:24:08 +053011127 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11128 sinfo->filled |= STATION_INFO_SIGNAL;
11129
c_hpothu09f19542014-05-30 21:53:31 +053011130 wlan_hdd_get_station_stats(pAdapter);
11131 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11132
11133 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011134 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11135 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
11136 sinfo->signal >= pCfg->linkSpeedRssiHigh))
11137 {
11138 rate_flags = pAdapter->maxRateFlags;
11139 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011140
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 //convert to the UI units of 100kbps
11142 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11143
11144#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011145 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 -070011146 sinfo->signal,
11147 pCfg->reportMaxLinkSpeed,
11148 myRate,
11149 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011150 (int) pCfg->linkSpeedRssiMid,
11151 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011152 (int) rate_flags,
11153 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011154#endif //LINKSPEED_DEBUG_ENABLED
11155
11156 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11157 {
11158 // we do not want to necessarily report the current speed
11159 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11160 {
11161 // report the max possible speed
11162 rssidx = 0;
11163 }
11164 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11165 {
11166 // report the max possible speed with RSSI scaling
11167 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11168 {
11169 // report the max possible speed
11170 rssidx = 0;
11171 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011172 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 {
11174 // report middle speed
11175 rssidx = 1;
11176 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011177 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11178 {
11179 // report middle speed
11180 rssidx = 2;
11181 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 else
11183 {
11184 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011185 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 }
11187 }
11188 else
11189 {
11190 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11191 hddLog(VOS_TRACE_LEVEL_ERROR,
11192 "%s: Invalid value for reportMaxLinkSpeed: %u",
11193 __func__, pCfg->reportMaxLinkSpeed);
11194 rssidx = 0;
11195 }
11196
11197 maxRate = 0;
11198
11199 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011200 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11201 OperationalRates, &ORLeng))
11202 {
11203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11204 /*To keep GUI happy*/
11205 return 0;
11206 }
11207
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 for (i = 0; i < ORLeng; i++)
11209 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011210 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 {
11212 /* Validate Rate Set */
11213 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11214 {
11215 currentRate = supported_data_rate[j].supported_rate[rssidx];
11216 break;
11217 }
11218 }
11219 /* Update MAX rate */
11220 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11221 }
11222
11223 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011224 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11225 ExtendedRates, &ERLeng))
11226 {
11227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11228 /*To keep GUI happy*/
11229 return 0;
11230 }
11231
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 for (i = 0; i < ERLeng; i++)
11233 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011234 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
11236 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11237 {
11238 currentRate = supported_data_rate[j].supported_rate[rssidx];
11239 break;
11240 }
11241 }
11242 /* Update MAX rate */
11243 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11244 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011245 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011246 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011247 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011248 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011249 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -070011250 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011251 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11252 MCSRates, &MCSLeng))
11253 {
11254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11255 /*To keep GUI happy*/
11256 return 0;
11257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011259#ifdef WLAN_FEATURE_11AC
11260 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011261 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011263 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011264 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011265 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011267 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011269 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011271 maxMCSIdx = 7;
11272 }
11273 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11274 {
11275 maxMCSIdx = 8;
11276 }
11277 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11278 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011279 //VHT20 is supporting 0~8
11280 if (rate_flags & eHAL_TX_RATE_VHT20)
11281 maxMCSIdx = 8;
11282 else
11283 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011284 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011285
11286 if (rate_flags & eHAL_TX_RATE_VHT80)
11287 {
11288 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11289 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11290 }
11291 else if (rate_flags & eHAL_TX_RATE_VHT40)
11292 {
11293 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11294 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11295 }
11296 else if (rate_flags & eHAL_TX_RATE_VHT20)
11297 {
11298 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11299 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11300 }
11301
Leo Chang6f8870f2013-03-26 18:11:36 -070011302 maxSpeedMCS = 1;
11303 if (currentRate > maxRate)
11304 {
11305 maxRate = currentRate;
11306 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011307
Leo Chang6f8870f2013-03-26 18:11:36 -070011308 }
11309 else
11310#endif /* WLAN_FEATURE_11AC */
11311 {
11312 if (rate_flags & eHAL_TX_RATE_HT40)
11313 {
11314 rateFlag |= 1;
11315 }
11316 if (rate_flags & eHAL_TX_RATE_SGI)
11317 {
11318 rateFlag |= 2;
11319 }
11320
11321 for (i = 0; i < MCSLeng; i++)
11322 {
11323 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
11324 for (j = 0; j < temp; j++)
11325 {
11326 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11327 {
11328 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11329 break;
11330 }
11331 }
11332 if ((j < temp) && (currentRate > maxRate))
11333 {
11334 maxRate = currentRate;
11335 maxSpeedMCS = 1;
11336 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11337 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 }
11339 }
11340 }
11341
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011342 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11343 {
11344 maxRate = myRate;
11345 maxSpeedMCS = 1;
11346 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11347 }
11348
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011350 if (((maxRate < myRate) && (0 == rssidx)) ||
11351 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 {
11353 maxRate = myRate;
11354 if (rate_flags & eHAL_TX_RATE_LEGACY)
11355 {
11356 maxSpeedMCS = 0;
11357 }
11358 else
11359 {
11360 maxSpeedMCS = 1;
11361 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11362 }
11363 }
11364
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011365 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 {
11367 sinfo->txrate.legacy = maxRate;
11368#ifdef LINKSPEED_DEBUG_ENABLED
11369 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11370#endif //LINKSPEED_DEBUG_ENABLED
11371 }
11372 else
11373 {
11374 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011375#ifdef WLAN_FEATURE_11AC
11376 sinfo->txrate.nss = 1;
11377 if (rate_flags & eHAL_TX_RATE_VHT80)
11378 {
11379 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011380 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011381 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011382 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011383 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011384 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11385 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11386 }
11387 else if (rate_flags & eHAL_TX_RATE_VHT20)
11388 {
11389 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11390 }
11391#endif /* WLAN_FEATURE_11AC */
11392 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11393 {
11394 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11395 if (rate_flags & eHAL_TX_RATE_HT40)
11396 {
11397 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11398 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 if (rate_flags & eHAL_TX_RATE_SGI)
11401 {
11402 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11403 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011404
Jeff Johnson295189b2012-06-20 16:38:30 -070011405#ifdef LINKSPEED_DEBUG_ENABLED
11406 pr_info("Reporting MCS rate %d flags %x\n",
11407 sinfo->txrate.mcs,
11408 sinfo->txrate.flags );
11409#endif //LINKSPEED_DEBUG_ENABLED
11410 }
11411 }
11412 else
11413 {
11414 // report current rate instead of max rate
11415
11416 if (rate_flags & eHAL_TX_RATE_LEGACY)
11417 {
11418 //provide to the UI in units of 100kbps
11419 sinfo->txrate.legacy = myRate;
11420#ifdef LINKSPEED_DEBUG_ENABLED
11421 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11422#endif //LINKSPEED_DEBUG_ENABLED
11423 }
11424 else
11425 {
11426 //must be MCS
11427 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011428#ifdef WLAN_FEATURE_11AC
11429 sinfo->txrate.nss = 1;
11430 if (rate_flags & eHAL_TX_RATE_VHT80)
11431 {
11432 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11433 }
11434 else
11435#endif /* WLAN_FEATURE_11AC */
11436 {
11437 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11438 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 if (rate_flags & eHAL_TX_RATE_SGI)
11440 {
11441 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11442 }
11443 if (rate_flags & eHAL_TX_RATE_HT40)
11444 {
11445 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11446 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011447#ifdef WLAN_FEATURE_11AC
11448 else if (rate_flags & eHAL_TX_RATE_VHT80)
11449 {
11450 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11451 }
11452#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011453#ifdef LINKSPEED_DEBUG_ENABLED
11454 pr_info("Reporting actual MCS rate %d flags %x\n",
11455 sinfo->txrate.mcs,
11456 sinfo->txrate.flags );
11457#endif //LINKSPEED_DEBUG_ENABLED
11458 }
11459 }
11460 sinfo->filled |= STATION_INFO_TX_BITRATE;
11461
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011462 sinfo->tx_packets =
11463 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11464 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11465 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11466 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11467
11468 sinfo->tx_retries =
11469 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11470 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11471 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11472 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11473
11474 sinfo->tx_failed =
11475 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11476 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11477 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11478 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11479
11480 sinfo->filled |=
11481 STATION_INFO_TX_PACKETS |
11482 STATION_INFO_TX_RETRIES |
11483 STATION_INFO_TX_FAILED;
11484
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011485 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11486 TRACE_CODE_HDD_CFG80211_GET_STA,
11487 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011488 EXIT();
11489 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011490}
11491
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011492static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11493 u8* mac, struct station_info *sinfo)
11494{
11495 int ret;
11496
11497 vos_ssr_protect(__func__);
11498 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11499 vos_ssr_unprotect(__func__);
11500
11501 return ret;
11502}
11503
11504static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011505 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011506{
11507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011508 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011510 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011511
Jeff Johnsone7245742012-09-05 17:12:55 -070011512 ENTER();
11513
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 if (NULL == pAdapter)
11515 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 return -ENODEV;
11518 }
11519
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011520 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11521 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11522 pAdapter->sessionId, timeout));
11523
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011525 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011526
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011527 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11530 "%s: HDD context is not valid", __func__);
11531 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011532 }
11533
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011534 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11535 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11536 (pHddCtx->cfg_ini->fhostArpOffload) &&
11537 (eConnectionState_Associated ==
11538 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11539 {
Amar Singhald53568e2013-09-26 11:03:45 -070011540
11541 hddLog(VOS_TRACE_LEVEL_INFO,
11542 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011543 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011544 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11545 {
11546 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011547 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011548 __func__, vos_status);
11549 }
11550 }
11551
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 /**The get power cmd from the supplicant gets updated by the nl only
11553 *on successful execution of the function call
11554 *we are oppositely mapped w.r.t mode in the driver
11555 **/
11556 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11557
Kiet Lam94fd2922014-06-18 19:12:43 -070011558 if (!mode)
11559 {
11560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11561 "%s: DHCP start indicated through power save", __func__);
11562
11563 pHddCtx->btCoexModeSet = TRUE;
11564 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
11565 pAdapter->sessionId);
11566 }
11567 else
11568 {
11569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11570 "%s: DHCP stop indicated through power save", __func__);
11571
11572 pHddCtx->btCoexModeSet = FALSE;
11573 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
11574 pAdapter->sessionId);
11575 }
11576
Jeff Johnsone7245742012-09-05 17:12:55 -070011577 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 if (VOS_STATUS_E_FAILURE == vos_status)
11579 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11581 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011582 return -EINVAL;
11583 }
11584 return 0;
11585}
11586
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011587static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11588 struct net_device *dev, bool mode, int timeout)
11589{
11590 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011591
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011592 vos_ssr_protect(__func__);
11593 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11594 vos_ssr_unprotect(__func__);
11595
11596 return ret;
11597}
Jeff Johnson295189b2012-06-20 16:38:30 -070011598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11599static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11600 struct net_device *netdev,
11601 u8 key_index)
11602{
Jeff Johnsone7245742012-09-05 17:12:55 -070011603 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 return 0;
11605}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011607
11608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11609static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11610 struct net_device *dev,
11611 struct ieee80211_txq_params *params)
11612{
Jeff Johnsone7245742012-09-05 17:12:55 -070011613 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 return 0;
11615}
11616#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11617static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11618 struct ieee80211_txq_params *params)
11619{
Jeff Johnsone7245742012-09-05 17:12:55 -070011620 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011621 return 0;
11622}
11623#endif //LINUX_VERSION_CODE
11624
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011625static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 struct net_device *dev, u8 *mac)
11627{
11628 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011629 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011630 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011631 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011632 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011633
Jeff Johnsone7245742012-09-05 17:12:55 -070011634 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011635
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011636 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 return -EINVAL;
11640 }
11641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11643 TRACE_CODE_HDD_CFG80211_DEL_STA,
11644 pAdapter->sessionId, pAdapter->device_mode));
11645
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11647 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011648
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011649 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011650 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11652 "%s: HDD context is not valid", __func__);
11653 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011654 }
11655
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 )
11659 {
11660 if( NULL == mac )
11661 {
11662 v_U16_t i;
11663 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11664 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011665 if ((pAdapter->aStaInfo[i].isUsed) &&
11666 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 {
11668 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11669 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011670 "%s: Delete STA with MAC::"
11671 MAC_ADDRESS_STR,
11672 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011673 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11674 if (VOS_IS_STATUS_SUCCESS(vos_status))
11675 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 }
11677 }
11678 }
11679 else
11680 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011681
11682 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11683 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11684 {
11685 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011686 "%s: Skip this DEL STA as this is not used::"
11687 MAC_ADDRESS_STR,
11688 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011689 return -ENOENT;
11690 }
11691
11692 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11693 {
11694 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011695 "%s: Skip this DEL STA as deauth is in progress::"
11696 MAC_ADDRESS_STR,
11697 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011698 return -ENOENT;
11699 }
11700
11701 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11702
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 hddLog(VOS_TRACE_LEVEL_INFO,
11704 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011705 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011707 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011708
11709 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11710 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11711 {
11712 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11713 hddLog(VOS_TRACE_LEVEL_INFO,
11714 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011715 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011716 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011717 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011718 return -ENOENT;
11719 }
11720
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 }
11722 }
11723
11724 EXIT();
11725
11726 return 0;
11727}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011728static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11729 struct net_device *dev, u8 *mac)
11730{
11731 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011732
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011733 vos_ssr_protect(__func__);
11734 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11735 vos_ssr_unprotect(__func__);
11736
11737 return ret;
11738}
11739
11740static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011741 struct net_device *dev, u8 *mac, struct station_parameters *params)
11742{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011744 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011745#ifdef FEATURE_WLAN_TDLS
11746 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011747 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011748
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11750 TRACE_CODE_HDD_CFG80211_ADD_STA,
11751 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011752 mask = params->sta_flags_mask;
11753
11754 set = params->sta_flags_set;
11755
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011756#ifdef WLAN_FEATURE_TDLS_DEBUG
11757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11758 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11759 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11760#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011761
11762 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11763 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011764 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011765 }
11766 }
11767#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011768 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011769}
11770
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011771static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11772 struct net_device *dev, u8 *mac, struct station_parameters *params)
11773{
11774 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011775
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011776 vos_ssr_protect(__func__);
11777 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11778 vos_ssr_unprotect(__func__);
11779
11780 return ret;
11781}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011782#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011783
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011784static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011785 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011786{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011789 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011790 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011792 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011793 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011795 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11796 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011797
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011798 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011799 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011800 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011802 return -EINVAL;
11803 }
11804
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011805 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11806 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011807
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011808 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011809 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11811 "%s: HDD context is not valid", __func__);
11812 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011813 }
11814
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011816 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011817 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011818
Agarwal Ashish3da95242014-05-21 14:57:17 +053011819 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011820 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011821 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011822 pmksa->bssid, WNI_CFG_BSSID_LEN))
11823 {
11824 /* BSSID matched previous entry. Overwrite it. */
11825 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011826 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011827 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011828 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011829 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011830 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011831 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011832 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011833 dump_bssid(pmksa->bssid);
11834 dump_pmkid(halHandle, pmksa->pmkid);
11835 break;
11836 }
11837 }
11838
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011839 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011840 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011841
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011842 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011843 {
11844 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011845 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011846 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011847 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011848 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011850 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11851 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852 dump_bssid(pmksa->bssid);
11853 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011854 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011855 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011856 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11857 pHddStaCtx->PMKIDCacheIndex++;
11858 else
11859 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011860 }
11861
11862
11863 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011864 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11865 __func__, pHddStaCtx->PMKIDCacheIndex );
11866
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011867 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011868 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011869 pHddStaCtx->PMKIDCache,
11870 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11872 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11873 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011874 return 0;
11875}
11876
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011877static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11878 struct cfg80211_pmksa *pmksa)
11879{
11880 int ret;
11881
11882 vos_ssr_protect(__func__);
11883 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11884 vos_ssr_unprotect(__func__);
11885
11886 return ret;
11887}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011888
Wilson Yang6507c4e2013-10-01 20:11:19 -070011889
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011890static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011891 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011892{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011893 tANI_U32 j=0;
11894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011895 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011896 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011897 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011898 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011899 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011900
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011901 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11902 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011903
11904 /* Validate pAdapter */
11905 if (NULL == pAdapter)
11906 {
11907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11908 return -EINVAL;
11909 }
11910
11911 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11912 status = wlan_hdd_validate_context(pHddCtx);
11913
11914 if (0 != status)
11915 {
11916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11917 "%s: HDD context is not valid", __func__);
11918 return status;
11919 }
11920
11921 /*Retrieve halHandle*/
11922 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011924
11925 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011926 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011927 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011928 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11929 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011930 }
11931
11932 /*find the matching PMKSA entry from j=0 to (index-1),
11933 * and delete the matched one
11934 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011935 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011936 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011937 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011938 pmksa->bssid,
11939 WNI_CFG_BSSID_LEN))
11940 {
11941 /* BSSID matched entry */
11942 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011943 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011944 {
11945 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011946 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
11947 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11948 VOS_MAC_ADDR_SIZE);
11949 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
11950 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11951 CSR_RSN_PMKID_SIZE);
11952 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070011953
11954 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011955 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
11956 VOS_MAC_ADDR_SIZE);
11957 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
11958 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011959 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011960 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011961 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080011962 if (eHAL_STATUS_SUCCESS !=
11963 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070011964 {
11965 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053011966 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080011967 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011968 }
11969
11970 dump_bssid(pmksa->bssid);
11971 dump_pmkid(halHandle,pmksa->pmkid);
11972
11973 break;
11974 }
11975 }
11976
11977 /* we compare all entries,but cannot find matching entry */
11978 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
11979 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011980 hddLog(VOS_TRACE_LEVEL_FATAL,
11981 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
11982 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011983 dump_bssid(pmksa->bssid);
11984 dump_pmkid(halHandle, pmksa->pmkid);
11985 return -EINVAL;
11986 }
Wilson Yangef657d32014-01-15 19:19:23 -080011987 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011988}
11989
Wilson Yang6507c4e2013-10-01 20:11:19 -070011990
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011991static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
11992 struct cfg80211_pmksa *pmksa)
11993{
11994 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011995
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011996 vos_ssr_protect(__func__);
11997 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
11998 vos_ssr_unprotect(__func__);
11999
12000 return ret;
12001
12002}
12003
12004static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012005{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012006 tANI_U32 j=0;
12007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012008 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012009 tHalHandle halHandle;
12010 hdd_context_t *pHddCtx;
12011 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012012 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012013
12014 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12015
12016 /* Validate pAdapter */
12017 if (NULL == pAdapter)
12018 {
12019 hddLog(VOS_TRACE_LEVEL_ERROR,
12020 "%s: Invalid Adapter" ,__func__);
12021 return -EINVAL;
12022 }
12023
12024 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12025 status = wlan_hdd_validate_context(pHddCtx);
12026
12027 if (0 != status)
12028 {
12029 hddLog(VOS_TRACE_LEVEL_ERROR,
12030 "%s: HDD context is not valid", __func__);
12031 return status;
12032 }
12033
12034 /*Retrieve halHandle*/
12035 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012036 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012037
12038 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012039 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012040 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012042 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012043 }
12044
12045 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012046 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012047 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012048 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012049 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012050 if (eHAL_STATUS_SUCCESS !=
12051 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012052 {
12053 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12054 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012055 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012056 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012057 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012058 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12059 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12060 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012061
Agarwal Ashish3da95242014-05-21 14:57:17 +053012062 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012063 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012064}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012065
12066static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12067{
12068 int ret;
12069
12070 vos_ssr_protect(__func__);
12071 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12072 vos_ssr_unprotect(__func__);
12073
12074 return ret;
12075}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012076#endif
12077
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012078#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012079static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12080 struct net_device *dev,
12081 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012082{
12083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12084 hdd_station_ctx_t *pHddStaCtx;
12085
12086 if (NULL == pAdapter)
12087 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012089 return -ENODEV;
12090 }
12091
12092 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12093
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012094 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12095 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12096 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012097 // Added for debug on reception of Re-assoc Req.
12098 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12099 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012100 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012101 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012102 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012103 }
12104
12105#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012106 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012107 ftie->ie_len);
12108#endif
12109
12110 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012111 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12112 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012113 ftie->ie_len);
12114 return 0;
12115}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012116
12117static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12118 struct net_device *dev,
12119 struct cfg80211_update_ft_ies_params *ftie)
12120{
12121 int ret;
12122
12123 vos_ssr_protect(__func__);
12124 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12125 vos_ssr_unprotect(__func__);
12126
12127 return ret;
12128}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012129#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012130
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012131#ifdef FEATURE_WLAN_SCAN_PNO
12132
12133void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12134 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12135{
12136 int ret;
12137 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12138 hdd_context_t *pHddCtx;
12139
Nirav Shah80830bf2013-12-31 16:35:12 +053012140 ENTER();
12141
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012142 if (NULL == pAdapter)
12143 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012145 "%s: HDD adapter is Null", __func__);
12146 return ;
12147 }
12148
12149 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12150 if (NULL == pHddCtx)
12151 {
12152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12153 "%s: HDD context is Null!!!", __func__);
12154 return ;
12155 }
12156
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012157 spin_lock(&pHddCtx->schedScan_lock);
12158 if (TRUE == pHddCtx->isWiphySuspended)
12159 {
12160 pHddCtx->isSchedScanUpdatePending = TRUE;
12161 spin_unlock(&pHddCtx->schedScan_lock);
12162 hddLog(VOS_TRACE_LEVEL_INFO,
12163 "%s: Update cfg80211 scan database after it resume", __func__);
12164 return ;
12165 }
12166 spin_unlock(&pHddCtx->schedScan_lock);
12167
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012168 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12169
12170 if (0 > ret)
12171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12172
12173 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12175 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012176}
12177
12178/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012179 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012180 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012181 */
12182static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12183{
12184 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12185 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012186 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12188 int status = 0;
12189 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12190
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012191 /* The current firmware design does not allow PNO during any
12192 * active sessions. Hence, determine the active sessions
12193 * and return a failure.
12194 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012195 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12196 {
12197 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012198 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012199
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012200 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12201 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12202 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12203 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12204 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12205 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012206 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012207 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012208 }
12209 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12210 pAdapterNode = pNext;
12211 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012212 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012213}
12214
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012215void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12216{
12217 hdd_adapter_t *pAdapter = callbackContext;
12218 hdd_context_t *pHddCtx;
12219
12220 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12221 {
12222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12223 FL("Invalid adapter or adapter has invalid magic"));
12224 return;
12225 }
12226
12227 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12228 if (0 != wlan_hdd_validate_context(pHddCtx))
12229 {
12230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12231 FL("HDD context is not valid"));
12232 return;
12233 }
12234
12235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12236 FL("PNO enable response status = %d"), status);
12237
12238 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12239 complete(&pAdapter->pno_comp_var);
12240}
12241
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012242/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012243 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12244 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012245 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012246static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012247 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12248{
12249 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12250 tpSirPNOScanReq pPnoRequest = NULL;
12251 hdd_context_t *pHddCtx;
12252 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012253 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012254 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12255 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012256 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12257 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012258 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012259
12260 if (NULL == pAdapter)
12261 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012263 "%s: HDD adapter is Null", __func__);
12264 return -ENODEV;
12265 }
12266
12267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012268 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012269
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012270 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012271 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12273 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012274 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012275 }
12276
12277 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12278 if (NULL == hHal)
12279 {
12280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12281 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012282 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012283 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012284
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012285 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012286 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012287 {
12288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12289 "%s: aborting the existing scan is unsuccessfull", __func__);
12290 return -EBUSY;
12291 }
12292
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012293 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012294 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012296 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012297 return -EBUSY;
12298 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012299
c_hpothu37f21312014-04-09 21:49:54 +053012300 if (TRUE == pHddCtx->isPnoEnable)
12301 {
12302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12303 FL("already PNO is enabled"));
12304 return -EBUSY;
12305 }
12306 pHddCtx->isPnoEnable = TRUE;
12307
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012308 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12309 if (NULL == pPnoRequest)
12310 {
12311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12312 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012313 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012314 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012315 }
12316
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012317 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012318 pPnoRequest->enable = 1; /*Enable PNO */
12319 pPnoRequest->ucNetworksCount = request->n_match_sets;
12320
12321 if (( !pPnoRequest->ucNetworksCount ) ||
12322 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12323 {
12324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012325 "%s: Network input is not correct %d Max Network supported is %d",
12326 __func__, pPnoRequest->ucNetworksCount,
12327 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012328 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012329 goto error;
12330 }
12331
12332 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12333 {
12334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012335 "%s: Incorrect number of channels %d",
12336 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012337 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012338 goto error;
12339 }
12340
12341 /* Framework provides one set of channels(all)
12342 * common for all saved profile */
12343 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12344 channels_allowed, &num_channels_allowed))
12345 {
12346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12347 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012348 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012349 goto error;
12350 }
12351 /* Checking each channel against allowed channel list */
12352 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012353 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012354 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012355 char chList [(request->n_channels*5)+1];
12356 int len;
12357 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012358 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012359 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012360 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012361 if (request->channels[i]->hw_value == channels_allowed[indx])
12362 {
12363 valid_ch[num_ch++] = request->channels[i]->hw_value;
12364 len += snprintf(chList+len, 5, "%d ",
12365 request->channels[i]->hw_value);
12366 break ;
12367 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012368 }
12369 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012370 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12371 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012372
12373 /* Filling per profile params */
12374 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12375 {
12376 pPnoRequest->aNetworks[i].ssId.length =
12377 request->match_sets[i].ssid.ssid_len;
12378
12379 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12380 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12381 {
12382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012383 "%s: SSID Len %d is not correct for network %d",
12384 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012385 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012386 goto error;
12387 }
12388
12389 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12390 request->match_sets[i].ssid.ssid,
12391 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12393 "%s: SSID of network %d is %s ", __func__,
12394 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012395 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12396 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12397 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12398
12399 /*Copying list of valid channel into request */
12400 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12401 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12402
12403 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12404 }
12405
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012407 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012408 if ((0 < request->ie_len) && (NULL != request->ie))
12409 {
12410 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12411 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12412 pPnoRequest->us24GProbeTemplateLen);
12413
12414 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12415 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12416 pPnoRequest->us5GProbeTemplateLen);
12417 }
12418
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012419 /* Driver gets only one time interval which is hardcoded in
12420 * supplicant for 10000ms. Taking power consumption into account 6 timers
12421 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12422 * 80,160,320 secs. And number of scan cycle for each timer
12423 * is configurable through INI param gPNOScanTimerRepeatValue.
12424 * If it is set to 0 only one timer will be used and PNO scan cycle
12425 * will be repeated after each interval specified by supplicant
12426 * till PNO is disabled.
12427 */
12428 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12429 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12430 else
12431 pPnoRequest->scanTimers.ucScanTimersCount =
12432 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12433
12434 tempInterval = (request->interval)/1000;
12435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12436 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12437 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12438 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12439 {
12440 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12441 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12442 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12443 tempInterval *= 2;
12444 }
12445 //Repeat last timer until pno disabled.
12446 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12447
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012448 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012449
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012450 INIT_COMPLETION(pAdapter->pno_comp_var);
12451 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12452 pPnoRequest->callbackContext = pAdapter;
12453 pAdapter->pno_req_status = 0;
12454
Nirav Shah80830bf2013-12-31 16:35:12 +053012455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12456 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12457 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12458 pPnoRequest->scanTimers.ucScanTimersCount);
12459
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012460 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12461 pPnoRequest, pAdapter->sessionId,
12462 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12463 if (eHAL_STATUS_SUCCESS != status)
12464 {
12465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012466 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012467 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012468 goto error;
12469 }
12470
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012471 ret = wait_for_completion_timeout(
12472 &pAdapter->pno_comp_var,
12473 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12474 if (0 >= ret)
12475 {
12476 // Did not receive the response for PNO enable in time.
12477 // Assuming the PNO enable was success.
12478 // Returning error from here, because we timeout, results
12479 // in side effect of Wifi (Wifi Setting) not to work.
12480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12481 FL("Timed out waiting for PNO to be Enabled"));
12482 ret = 0;
12483 goto error;
12484 }
12485
12486 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012487 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012488
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012489error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12491 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012492 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012493 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012494 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012495}
12496
12497/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012498 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12499 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012500 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012501static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12502 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12503{
12504 int ret;
12505
12506 vos_ssr_protect(__func__);
12507 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12508 vos_ssr_unprotect(__func__);
12509
12510 return ret;
12511}
12512
12513/*
12514 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12515 * Function to disable PNO
12516 */
12517static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012518 struct net_device *dev)
12519{
12520 eHalStatus status = eHAL_STATUS_FAILURE;
12521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12522 hdd_context_t *pHddCtx;
12523 tHalHandle hHal;
12524 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012525 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012526
12527 ENTER();
12528
12529 if (NULL == pAdapter)
12530 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012532 "%s: HDD adapter is Null", __func__);
12533 return -ENODEV;
12534 }
12535
12536 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012537
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012538 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012539 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012541 "%s: HDD context is Null", __func__);
12542 return -ENODEV;
12543 }
12544
12545 /* The return 0 is intentional when isLogpInProgress and
12546 * isLoadUnloadInProgress. We did observe a crash due to a return of
12547 * failure in sched_scan_stop , especially for a case where the unload
12548 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12549 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12550 * success. If it returns a failure , then its next invocation due to the
12551 * clean up of the second interface will have the dev pointer corresponding
12552 * to the first one leading to a crash.
12553 */
12554 if (pHddCtx->isLogpInProgress)
12555 {
12556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12557 "%s: LOGP in Progress. Ignore!!!", __func__);
12558 return ret;
12559 }
12560
Mihir Shete18156292014-03-11 15:38:30 +053012561 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012562 {
12563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12564 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12565 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012566 }
12567
12568 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12569 if (NULL == hHal)
12570 {
12571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12572 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012573 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012574 }
12575
12576 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12577 if (NULL == pPnoRequest)
12578 {
12579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12580 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012581 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012582 }
12583
12584 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12585 pPnoRequest->enable = 0; /* Disable PNO */
12586 pPnoRequest->ucNetworksCount = 0;
12587
12588 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12589 pAdapter->sessionId,
12590 NULL, pAdapter);
12591 if (eHAL_STATUS_SUCCESS != status)
12592 {
12593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12594 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012595 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012596 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012597 }
c_hpothu37f21312014-04-09 21:49:54 +053012598 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012599
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012600error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012602 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012603 vos_mem_free(pPnoRequest);
12604
12605 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012606 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012607}
12608
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012609/*
12610 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12611 * NL interface to disable PNO
12612 */
12613static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12614 struct net_device *dev)
12615{
12616 int ret;
12617
12618 vos_ssr_protect(__func__);
12619 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12620 vos_ssr_unprotect(__func__);
12621
12622 return ret;
12623}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012624#endif /*FEATURE_WLAN_SCAN_PNO*/
12625
12626
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012627#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012628#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012629static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12630 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012631 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12632#else
12633static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12634 u8 *peer, u8 action_code, u8 dialog_token,
12635 u16 status_code, const u8 *buf, size_t len)
12636#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012637{
12638
12639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12640 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012641 u8 peerMac[6];
12642 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012643 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012644 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012645 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012646#if !(TDLS_MGMT_VERSION2)
12647 u32 peer_capability = 0;
12648#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012649 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12652 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12653 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012654 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012657 "Invalid arguments");
12658 return -EINVAL;
12659 }
12660
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012661 if (pHddCtx->isLogpInProgress)
12662 {
12663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12664 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012665 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012666 return -EBUSY;
12667 }
12668
Hoonki Lee27511902013-03-14 18:19:06 -070012669 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012670 {
Hoonki Lee27511902013-03-14 18:19:06 -070012671 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12672 "%s: TDLS mode is disabled OR not enabled in FW."
12673 MAC_ADDRESS_STR " action %d declined.",
12674 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012675 return -ENOTSUPP;
12676 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012677
Hoonki Lee27511902013-03-14 18:19:06 -070012678 /* other than teardown frame, other mgmt frames are not sent if disabled */
12679 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12680 {
12681 /* if tdls_mode is disabled to respond to peer's request */
12682 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12683 {
12684 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12685 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012686 " TDLS mode is disabled. action %d declined.",
12687 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012688
12689 return -ENOTSUPP;
12690 }
12691 }
12692
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012693 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12694 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012695 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012696 {
12697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012698 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012699 " TDLS setup is ongoing. action %d declined.",
12700 __func__, MAC_ADDR_ARRAY(peer), action_code);
12701 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012702 }
12703 }
12704
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012705 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12706 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012707 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012708 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12709 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012710 {
12711 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12712 we return error code at 'add_station()'. Hence we have this
12713 check again in addtion to add_station().
12714 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012715 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012716 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12718 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012719 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12720 __func__, MAC_ADDR_ARRAY(peer), action_code,
12721 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012722 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012723 }
12724 else
12725 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012726 /* maximum reached. tweak to send error code to peer and return
12727 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012728 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12730 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012731 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12732 __func__, MAC_ADDR_ARRAY(peer), status_code,
12733 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012734 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012735 /* fall through to send setup resp with failure status
12736 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012737 }
12738 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012739 else
12740 {
12741 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012742 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012743 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012744 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012746 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12747 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012748 return -EPERM;
12749 }
12750 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012751 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012752 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012753
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012754#ifdef WLAN_FEATURE_TDLS_DEBUG
12755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012756 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012757 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12758 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012759#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012760
Hoonki Leea34dd892013-02-05 22:56:02 -080012761 /*Except teardown responder will not be used so just make 0*/
12762 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012763 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012764 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012765
12766 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012767 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012768
12769 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12770 responder = pTdlsPeer->is_responder;
12771 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012772 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012774 "%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 -070012775 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12776 dialog_token, status_code, len);
12777 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012778 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012779 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012780
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012781 /* For explicit trigger of DIS_REQ come out of BMPS for
12782 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012783 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012784 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12785 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012786 {
12787 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12788 {
12789 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012790 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012791 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12792 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012793 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12794 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012795 }
12796
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012797 /* make sure doesn't call send_mgmt() while it is pending */
12798 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12799 {
12800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012801 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012802 __func__, MAC_ADDR_ARRAY(peer), action_code);
12803 return -EBUSY;
12804 }
12805
12806 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012807 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12808
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012809 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012810 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012811
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012812 if (VOS_STATUS_SUCCESS != status)
12813 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12815 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012816 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012817 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012818 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012819 }
12820
Hoonki Leed37cbb32013-04-20 00:31:14 -070012821 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12822 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12823
12824 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012825 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012827 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012828 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012829 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012830
12831 if (pHddCtx->isLogpInProgress)
12832 {
12833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12834 "%s: LOGP in Progress. Ignore!!!", __func__);
12835 return -EAGAIN;
12836 }
12837
Hoonki Leed37cbb32013-04-20 00:31:14 -070012838 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012839 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012840 }
12841
Gopichand Nakkala05922802013-03-14 12:23:19 -070012842 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012843 {
12844 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012845 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012846 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012847
Hoonki Leea34dd892013-02-05 22:56:02 -080012848 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12849 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012850 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012851 }
12852 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12853 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012854 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012855 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012856
12857 return 0;
12858}
12859
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012860static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012861 u8 *peer, enum nl80211_tdls_operation oper)
12862{
12863 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12864 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012865 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012866 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012867
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012868 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12869 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12870 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012871 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012872 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012874 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012875 return -EINVAL;
12876 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012877
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012878 status = wlan_hdd_validate_context(pHddCtx);
12879
12880 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012881 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12883 "%s: HDD context is not valid", __func__);
12884 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012885 }
12886
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012887
12888 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012889 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012890 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012892 "TDLS Disabled in INI OR not enabled in FW. "
12893 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012894 return -ENOTSUPP;
12895 }
12896
12897 switch (oper) {
12898 case NL80211_TDLS_ENABLE_LINK:
12899 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012900 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012901 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012902 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012903
Sunil Dutt41de4e22013-11-14 18:09:02 +053012904 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12905
12906 if ( NULL == pTdlsPeer ) {
12907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12908 " (oper %d) not exsting. ignored",
12909 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12910 return -EINVAL;
12911 }
12912
12913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12914 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12915 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12916 "NL80211_TDLS_ENABLE_LINK");
12917
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012918 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12919 {
12920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12921 MAC_ADDRESS_STR " failed",
12922 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12923 return -EINVAL;
12924 }
12925
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012926 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012927 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012928 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053012929
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012930 if (0 != wlan_hdd_tdls_get_link_establish_params(
12931 pAdapter, peer,&tdlsLinkEstablishParams)) {
12932 return -EINVAL;
12933 }
12934 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012935
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053012936 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
12937 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
12938 /* Send TDLS peer UAPSD capabilities to the firmware and
12939 * register with the TL on after the response for this operation
12940 * is received .
12941 */
12942 ret = wait_for_completion_interruptible_timeout(
12943 &pAdapter->tdls_link_establish_req_comp,
12944 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
12945 if (ret <= 0)
12946 {
12947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12948 "%s: Link Establish Request Faled Status %ld",
12949 __func__, ret);
12950 return -EINVAL;
12951 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012952 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012953 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053012954 /* Mark TDLS client Authenticated .*/
12955 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
12956 pTdlsPeer->staId,
12957 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012958 if (VOS_STATUS_SUCCESS == status)
12959 {
Hoonki Lee14621352013-04-16 17:51:19 -070012960 if (pTdlsPeer->is_responder == 0)
12961 {
12962 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
12963
12964 wlan_hdd_tdls_timer_restart(pAdapter,
12965 &pTdlsPeer->initiatorWaitTimeoutTimer,
12966 WAIT_TIME_TDLS_INITIATOR);
12967 /* suspend initiator TX until it receives direct packet from the
12968 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
12969 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12970 &staId, NULL);
12971 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070012972 wlan_hdd_tdls_increment_peer_count(pAdapter);
12973 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012974 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012975
12976 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012977 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
12978 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012979 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053012980 int ac;
12981 uint8 ucAc[4] = { WLANTL_AC_VO,
12982 WLANTL_AC_VI,
12983 WLANTL_AC_BK,
12984 WLANTL_AC_BE };
12985 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
12986 for(ac=0; ac < 4; ac++)
12987 {
12988 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
12989 pTdlsPeer->staId, ucAc[ac],
12990 tlTid[ac], tlTid[ac], 0, 0,
12991 WLANTL_BI_DIR );
12992 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012993 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012994 }
12995
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012996 }
12997 break;
12998 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080012999 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013000 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13001
13002 if ( NULL == pTdlsPeer ) {
13003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13004 " (oper %d) not exsting. ignored",
13005 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13006 return -EINVAL;
13007 }
13008
13009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13010 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13011 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13012 "NL80211_TDLS_DISABLE_LINK");
13013
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013014 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013015 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013016 long status;
13017
13018 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13019
Lee Hoonkic1262f22013-01-24 21:59:00 -080013020 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13021 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013022
13023 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13024 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13025 if (status <= 0)
13026 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013027 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13029 "%s: Del station failed status %ld",
13030 __func__, status);
13031 return -EPERM;
13032 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013033 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013034 }
13035 else
13036 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13038 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013039 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013040 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013041 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013042 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013043 {
13044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13045 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13046 __func__, MAC_ADDR_ARRAY(peer));
13047
13048 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13049 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13050
13051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13052 " %s TDLS External control and Implicit Trigger not enabled ",
13053 __func__);
13054 return -ENOTSUPP;
13055 }
13056
Sunil Dutt41de4e22013-11-14 18:09:02 +053013057
13058 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13059
13060 if ( NULL == pTdlsPeer ) {
13061 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13062 " peer not exsting",
13063 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013064 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013065 }
13066 else {
13067 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13068 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13069 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013070
13071 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13072 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013073 break;
13074 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013075 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013076 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013077 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13079 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13080 __func__, MAC_ADDR_ARRAY(peer));
13081
13082 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13083 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13084
13085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13086 " %s TDLS External control and Implicit Trigger not enabled ",
13087 __func__);
13088 return -ENOTSUPP;
13089 }
13090
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013091 /* To cater the requirement of establishing the TDLS link
13092 * irrespective of the data traffic , get an entry of TDLS peer.
13093 */
13094 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13095 if (pTdlsPeer == NULL) {
13096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13097 "%s: peer " MAC_ADDRESS_STR " not existing",
13098 __func__, MAC_ADDR_ARRAY(peer));
13099 return -EINVAL;
13100 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013101
13102 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13103
13104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13105 " %s TDLS Add Force Peer Failed",
13106 __func__);
13107 return -EINVAL;
13108 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013109 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013110 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013111 case NL80211_TDLS_DISCOVERY_REQ:
13112 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13114 "%s: We don't support in-driver setup/teardown/discovery "
13115 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013116 return -ENOTSUPP;
13117 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13119 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013120 return -ENOTSUPP;
13121 }
13122 return 0;
13123}
Chilam NG571c65a2013-01-19 12:27:36 +053013124
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013125static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13126 u8 *peer, enum nl80211_tdls_operation oper)
13127{
13128 int ret;
13129
13130 vos_ssr_protect(__func__);
13131 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13132 vos_ssr_unprotect(__func__);
13133
13134 return ret;
13135}
13136
Chilam NG571c65a2013-01-19 12:27:36 +053013137int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13138 struct net_device *dev, u8 *peer)
13139{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013140 hddLog(VOS_TRACE_LEVEL_INFO,
13141 "tdls send discover req: "MAC_ADDRESS_STR,
13142 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013143
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013144#if TDLS_MGMT_VERSION2
13145 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13146 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13147#else
Chilam NG571c65a2013-01-19 12:27:36 +053013148 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13149 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013150#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013151}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013152#endif
13153
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013154#ifdef WLAN_FEATURE_GTK_OFFLOAD
13155/*
13156 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13157 * Callback rountine called upon receiving response for
13158 * get offload info
13159 */
13160void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13161 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13162{
13163
13164 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013165 tANI_U8 tempReplayCounter[8];
13166 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013167
13168 ENTER();
13169
13170 if (NULL == pAdapter)
13171 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013173 "%s: HDD adapter is Null", __func__);
13174 return ;
13175 }
13176
13177 if (NULL == pGtkOffloadGetInfoRsp)
13178 {
13179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13180 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13181 return ;
13182 }
13183
13184 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13185 {
13186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13187 "%s: wlan Failed to get replay counter value",
13188 __func__);
13189 return ;
13190 }
13191
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13193 /* Update replay counter */
13194 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13195 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13196
13197 {
13198 /* changing from little to big endian since supplicant
13199 * works on big endian format
13200 */
13201 int i;
13202 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13203
13204 for (i = 0; i < 8; i++)
13205 {
13206 tempReplayCounter[7-i] = (tANI_U8)p[i];
13207 }
13208 }
13209
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013210 /* Update replay counter to NL */
13211 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013212 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013213}
13214
13215/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013216 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013217 * This function is used to offload GTK rekeying job to the firmware.
13218 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013219int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013220 struct cfg80211_gtk_rekey_data *data)
13221{
13222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13223 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13224 hdd_station_ctx_t *pHddStaCtx;
13225 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013226 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013227 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013228 eHalStatus status = eHAL_STATUS_FAILURE;
13229
13230 ENTER();
13231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013232
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013233 if (NULL == pAdapter)
13234 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013236 "%s: HDD adapter is Null", __func__);
13237 return -ENODEV;
13238 }
13239
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013240 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13241 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13242 pAdapter->sessionId, pAdapter->device_mode));
13243
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013244 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013245
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013246 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013247 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13249 "%s: HDD context is not valid", __func__);
13250 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013251 }
13252
13253 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13254 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13255 if (NULL == hHal)
13256 {
13257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13258 "%s: HAL context is Null!!!", __func__);
13259 return -EAGAIN;
13260 }
13261
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013262 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13263 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13264 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13265 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013266 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013267 {
13268 /* changing from big to little endian since driver
13269 * works on little endian format
13270 */
13271 tANI_U8 *p =
13272 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13273 int i;
13274
13275 for (i = 0; i < 8; i++)
13276 {
13277 p[7-i] = data->replay_ctr[i];
13278 }
13279 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013280
13281 if (TRUE == pHddCtx->hdd_wlan_suspended)
13282 {
13283 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013284 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13285 sizeof (tSirGtkOffloadParams));
13286 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013287 pAdapter->sessionId);
13288
13289 if (eHAL_STATUS_SUCCESS != status)
13290 {
13291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13292 "%s: sme_SetGTKOffload failed, returned %d",
13293 __func__, status);
13294 return status;
13295 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13297 "%s: sme_SetGTKOffload successfull", __func__);
13298 }
13299 else
13300 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13302 "%s: wlan not suspended GTKOffload request is stored",
13303 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013304 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013305
13306 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013307}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013308
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013309int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13310 struct cfg80211_gtk_rekey_data *data)
13311{
13312 int ret;
13313
13314 vos_ssr_protect(__func__);
13315 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13316 vos_ssr_unprotect(__func__);
13317
13318 return ret;
13319}
13320#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013321/*
13322 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13323 * This function is used to set access control policy
13324 */
13325static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13326 struct net_device *dev, const struct cfg80211_acl_data *params)
13327{
13328 int i;
13329 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13330 hdd_hostapd_state_t *pHostapdState;
13331 tsap_Config_t *pConfig;
13332 v_CONTEXT_t pVosContext = NULL;
13333 hdd_context_t *pHddCtx;
13334 int status;
13335
13336 ENTER();
13337
13338 if (NULL == pAdapter)
13339 {
13340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13341 "%s: HDD adapter is Null", __func__);
13342 return -ENODEV;
13343 }
13344
13345 if (NULL == params)
13346 {
13347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13348 "%s: params is Null", __func__);
13349 return -EINVAL;
13350 }
13351
13352 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13353 status = wlan_hdd_validate_context(pHddCtx);
13354
13355 if (0 != status)
13356 {
13357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13358 "%s: HDD context is not valid", __func__);
13359 return status;
13360 }
13361
13362 pVosContext = pHddCtx->pvosContext;
13363 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13364
13365 if (NULL == pHostapdState)
13366 {
13367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13368 "%s: pHostapdState is Null", __func__);
13369 return -EINVAL;
13370 }
13371
13372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13373 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13374
13375 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13376 {
13377 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13378
13379 /* default value */
13380 pConfig->num_accept_mac = 0;
13381 pConfig->num_deny_mac = 0;
13382
13383 /**
13384 * access control policy
13385 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13386 * listed in hostapd.deny file.
13387 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13388 * listed in hostapd.accept file.
13389 */
13390 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13391 {
13392 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13393 }
13394 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13395 {
13396 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13397 }
13398 else
13399 {
13400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13401 "%s:Acl Policy : %d is not supported",
13402 __func__, params->acl_policy);
13403 return -ENOTSUPP;
13404 }
13405
13406 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13407 {
13408 pConfig->num_accept_mac = params->n_acl_entries;
13409 for (i = 0; i < params->n_acl_entries; i++)
13410 {
13411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13412 "** Add ACL MAC entry %i in WhiletList :"
13413 MAC_ADDRESS_STR, i,
13414 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13415
13416 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13417 sizeof(qcmacaddr));
13418 }
13419 }
13420 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13421 {
13422 pConfig->num_deny_mac = params->n_acl_entries;
13423 for (i = 0; i < params->n_acl_entries; i++)
13424 {
13425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13426 "** Add ACL MAC entry %i in BlackList :"
13427 MAC_ADDRESS_STR, i,
13428 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13429
13430 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13431 sizeof(qcmacaddr));
13432 }
13433 }
13434
13435 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13436 {
13437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13438 "%s: SAP Set Mac Acl fail", __func__);
13439 return -EINVAL;
13440 }
13441 }
13442 else
13443 {
13444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013445 "%s: Invalid device_mode = %s (%d)",
13446 __func__, hdd_device_modetoString(pAdapter->device_mode),
13447 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013448 return -EINVAL;
13449 }
13450
13451 return 0;
13452}
13453
Leo Chang9056f462013-08-01 19:21:11 -070013454#ifdef WLAN_NL80211_TESTMODE
13455#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013456void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013457(
13458 void *pAdapter,
13459 void *indCont
13460)
13461{
Leo Changd9df8aa2013-09-26 13:32:26 -070013462 tSirLPHBInd *lphbInd;
13463 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013464 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013465
13466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013467 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013468
c_hpothu73f35e62014-04-18 13:40:08 +053013469 if (pAdapter == NULL)
13470 {
13471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13472 "%s: pAdapter is NULL\n",__func__);
13473 return;
13474 }
13475
Leo Chang9056f462013-08-01 19:21:11 -070013476 if (NULL == indCont)
13477 {
13478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013479 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013480 return;
13481 }
13482
c_hpothu73f35e62014-04-18 13:40:08 +053013483 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013484 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013485 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013486 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013487 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013488 GFP_ATOMIC);
13489 if (!skb)
13490 {
13491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13492 "LPHB timeout, NL buffer alloc fail");
13493 return;
13494 }
13495
Leo Changac3ba772013-10-07 09:47:04 -070013496 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013497 {
13498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13499 "WLAN_HDD_TM_ATTR_CMD put fail");
13500 goto nla_put_failure;
13501 }
Leo Changac3ba772013-10-07 09:47:04 -070013502 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013503 {
13504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13505 "WLAN_HDD_TM_ATTR_TYPE put fail");
13506 goto nla_put_failure;
13507 }
Leo Changac3ba772013-10-07 09:47:04 -070013508 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013509 sizeof(tSirLPHBInd), lphbInd))
13510 {
13511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13512 "WLAN_HDD_TM_ATTR_DATA put fail");
13513 goto nla_put_failure;
13514 }
Leo Chang9056f462013-08-01 19:21:11 -070013515 cfg80211_testmode_event(skb, GFP_ATOMIC);
13516 return;
13517
13518nla_put_failure:
13519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13520 "NLA Put fail");
13521 kfree_skb(skb);
13522
13523 return;
13524}
13525#endif /* FEATURE_WLAN_LPHB */
13526
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013527static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013528{
13529 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13530 int err = 0;
13531#ifdef FEATURE_WLAN_LPHB
13532 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013533 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013534#endif /* FEATURE_WLAN_LPHB */
13535
13536 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13537 if (err)
13538 {
13539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13540 "%s Testmode INV ATTR", __func__);
13541 return err;
13542 }
13543
13544 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13545 {
13546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13547 "%s Testmode INV CMD", __func__);
13548 return -EINVAL;
13549 }
13550
13551 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13552 {
13553#ifdef FEATURE_WLAN_LPHB
13554 /* Low Power Heartbeat configuration request */
13555 case WLAN_HDD_TM_CMD_WLAN_HB:
13556 {
13557 int buf_len;
13558 void *buf;
13559 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013560 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013561
13562 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13563 {
13564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13565 "%s Testmode INV DATA", __func__);
13566 return -EINVAL;
13567 }
13568
13569 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13570 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013571
13572 hb_params_temp =(tSirLPHBReq *)buf;
13573 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13574 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13575 return -EINVAL;
13576
Leo Chang9056f462013-08-01 19:21:11 -070013577 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13578 if (NULL == hb_params)
13579 {
13580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13581 "%s Request Buffer Alloc Fail", __func__);
13582 return -EINVAL;
13583 }
13584
13585 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013586 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13587 hb_params,
13588 wlan_hdd_cfg80211_lphb_ind_handler);
13589 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013590 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13592 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013593 vos_mem_free(hb_params);
13594 }
Leo Chang9056f462013-08-01 19:21:11 -070013595 return 0;
13596 }
13597#endif /* FEATURE_WLAN_LPHB */
13598 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13600 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013601 return -EOPNOTSUPP;
13602 }
13603
13604 return err;
13605}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013606
13607static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13608{
13609 int ret;
13610
13611 vos_ssr_protect(__func__);
13612 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13613 vos_ssr_unprotect(__func__);
13614
13615 return ret;
13616}
Leo Chang9056f462013-08-01 19:21:11 -070013617#endif /* CONFIG_NL80211_TESTMODE */
13618
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013619static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013620 struct net_device *dev,
13621 int idx, struct survey_info *survey)
13622{
13623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13624 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013625 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013626 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013627 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013628 v_S7_t snr,rssi;
13629 int status, i, j, filled = 0;
13630
13631 ENTER();
13632
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013633 if (NULL == pAdapter)
13634 {
13635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13636 "%s: HDD adapter is Null", __func__);
13637 return -ENODEV;
13638 }
13639
13640 if (NULL == wiphy)
13641 {
13642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13643 "%s: wiphy is Null", __func__);
13644 return -ENODEV;
13645 }
13646
13647 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13648 status = wlan_hdd_validate_context(pHddCtx);
13649
13650 if (0 != status)
13651 {
13652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13653 "%s: HDD context is not valid", __func__);
13654 return status;
13655 }
13656
Mihir Sheted9072e02013-08-21 17:02:29 +053013657 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13658
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013659 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013660 0 != pAdapter->survey_idx ||
13661 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013662 {
13663 /* The survey dump ops when implemented completely is expected to
13664 * return a survey of all channels and the ops is called by the
13665 * kernel with incremental values of the argument 'idx' till it
13666 * returns -ENONET. But we can only support the survey for the
13667 * operating channel for now. survey_idx is used to track
13668 * that the ops is called only once and then return -ENONET for
13669 * the next iteration
13670 */
13671 pAdapter->survey_idx = 0;
13672 return -ENONET;
13673 }
13674
13675 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13676
13677 wlan_hdd_get_snr(pAdapter, &snr);
13678 wlan_hdd_get_rssi(pAdapter, &rssi);
13679
13680 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13681 hdd_wlan_get_freq(channel, &freq);
13682
13683
13684 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13685 {
13686 if (NULL == wiphy->bands[i])
13687 {
13688 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13689 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13690 continue;
13691 }
13692
13693 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13694 {
13695 struct ieee80211_supported_band *band = wiphy->bands[i];
13696
13697 if (band->channels[j].center_freq == (v_U16_t)freq)
13698 {
13699 survey->channel = &band->channels[j];
13700 /* The Rx BDs contain SNR values in dB for the received frames
13701 * while the supplicant expects noise. So we calculate and
13702 * return the value of noise (dBm)
13703 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13704 */
13705 survey->noise = rssi - snr;
13706 survey->filled = SURVEY_INFO_NOISE_DBM;
13707 filled = 1;
13708 }
13709 }
13710 }
13711
13712 if (filled)
13713 pAdapter->survey_idx = 1;
13714 else
13715 {
13716 pAdapter->survey_idx = 0;
13717 return -ENONET;
13718 }
13719
13720 return 0;
13721}
13722
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013723static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13724 struct net_device *dev,
13725 int idx, struct survey_info *survey)
13726{
13727 int ret;
13728
13729 vos_ssr_protect(__func__);
13730 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13731 vos_ssr_unprotect(__func__);
13732
13733 return ret;
13734}
13735
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013736/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013737 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013738 * this is called when cfg80211 driver resume
13739 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13740 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013741int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013742{
13743 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13744 hdd_adapter_t *pAdapter;
13745 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13746 VOS_STATUS status = VOS_STATUS_SUCCESS;
13747
13748 ENTER();
13749
13750 if ( NULL == pHddCtx )
13751 {
13752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13753 "%s: HddCtx validation failed", __func__);
13754 return 0;
13755 }
13756
13757 if (pHddCtx->isLogpInProgress)
13758 {
13759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13760 "%s: LOGP in Progress. Ignore!!!", __func__);
13761 return 0;
13762 }
13763
Mihir Shete18156292014-03-11 15:38:30 +053013764 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013765 {
13766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13767 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13768 return 0;
13769 }
13770
13771 spin_lock(&pHddCtx->schedScan_lock);
13772 pHddCtx->isWiphySuspended = FALSE;
13773 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13774 {
13775 spin_unlock(&pHddCtx->schedScan_lock);
13776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13777 "%s: Return resume is not due to PNO indication", __func__);
13778 return 0;
13779 }
13780 // Reset flag to avoid updatating cfg80211 data old results again
13781 pHddCtx->isSchedScanUpdatePending = FALSE;
13782 spin_unlock(&pHddCtx->schedScan_lock);
13783
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013784
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013785 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13786
13787 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13788 {
13789 pAdapter = pAdapterNode->pAdapter;
13790 if ( (NULL != pAdapter) &&
13791 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13792 {
13793 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013794 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13796 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013797 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013798 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013799 {
13800 /* Acquire wakelock to handle the case where APP's tries to
13801 * suspend immediately after updating the scan results. Whis
13802 * results in app's is in suspended state and not able to
13803 * process the connect request to AP
13804 */
13805 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013806 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013807 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013808
13809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13810 "%s : cfg80211 scan result database updated", __func__);
13811
13812 return 0;
13813
13814 }
13815 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13816 pAdapterNode = pNext;
13817 }
13818
13819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13820 "%s: Failed to find Adapter", __func__);
13821 return 0;
13822}
13823
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013824int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13825{
13826 int ret;
13827
13828 vos_ssr_protect(__func__);
13829 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13830 vos_ssr_unprotect(__func__);
13831
13832 return ret;
13833}
13834
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013835/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013836 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013837 * this is called when cfg80211 driver suspends
13838 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013839int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013840 struct cfg80211_wowlan *wow)
13841{
13842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13843
13844 ENTER();
13845 if (NULL == pHddCtx)
13846 {
13847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13848 "%s: HddCtx validation failed", __func__);
13849 return 0;
13850 }
13851
13852 pHddCtx->isWiphySuspended = TRUE;
13853
13854 EXIT();
13855
13856 return 0;
13857}
13858
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013859int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13860 struct cfg80211_wowlan *wow)
13861{
13862 int ret;
13863
13864 vos_ssr_protect(__func__);
13865 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13866 vos_ssr_unprotect(__func__);
13867
13868 return ret;
13869}
Jeff Johnson295189b2012-06-20 16:38:30 -070013870/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013872{
13873 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13874 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13875 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13876 .change_station = wlan_hdd_change_station,
13877#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13878 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13879 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13880 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013881#else
13882 .start_ap = wlan_hdd_cfg80211_start_ap,
13883 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13884 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013885#endif
13886 .change_bss = wlan_hdd_cfg80211_change_bss,
13887 .add_key = wlan_hdd_cfg80211_add_key,
13888 .get_key = wlan_hdd_cfg80211_get_key,
13889 .del_key = wlan_hdd_cfg80211_del_key,
13890 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013891#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013893#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 .scan = wlan_hdd_cfg80211_scan,
13895 .connect = wlan_hdd_cfg80211_connect,
13896 .disconnect = wlan_hdd_cfg80211_disconnect,
13897 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13898 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13899 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13900 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13901 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13903 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013904 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13906 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13907 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13908 .set_txq_params = wlan_hdd_set_txq_params,
13909#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 .get_station = wlan_hdd_cfg80211_get_station,
13911 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13912 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013913 .add_station = wlan_hdd_cfg80211_add_station,
13914#ifdef FEATURE_WLAN_LFR
13915 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13916 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13917 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13918#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013919#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13920 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13921#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013922#ifdef FEATURE_WLAN_TDLS
13923 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13924 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
13925#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013926#ifdef WLAN_FEATURE_GTK_OFFLOAD
13927 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
13928#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013929#ifdef FEATURE_WLAN_SCAN_PNO
13930 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
13931 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
13932#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013933 .resume = wlan_hdd_cfg80211_resume_wlan,
13934 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013935 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070013936#ifdef WLAN_NL80211_TESTMODE
13937 .testmode_cmd = wlan_hdd_cfg80211_testmode,
13938#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013939 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013940};
13941